diff --git a/docs/index.rst b/docs/index.rst index 5b29caf..68a99b0 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -87,6 +87,19 @@ define will appear on the ``.ak`` accessor or can be used for ufunc and operator overloads. +Sub-accessors +~~~~~~~~~~~~~ + +As an alternative to the object-oriented behaviours, developers may create +accessor namespaces that appear under ``.ak`` similar to the the builtin +``.ak.str`` (strings ops) snd ``.ak.dt`` (datetime ops) included already. + +One experimental proof-of-concept is `akimbo-ip`_, which provides fast vectorised +manipulations of IPv4/6 addresses and networks; and by using this through +the ``akimbo`` system, you can apply these methods to ragged/nested dataframes. + +.. _akimbo-ip: https://github.com/intake/akimbo-ip + .. toctree:: :maxdepth: 1 :caption: User Guide diff --git a/src/akimbo/mixin.py b/src/akimbo/mixin.py index 09d0ab9..74923cb 100644 --- a/src/akimbo/mixin.py +++ b/src/akimbo/mixin.py @@ -232,6 +232,30 @@ def register_accessor(cls, name, klass): # TODO: check clobber? cls.subaccessors[name] = klass + def rename(self, where, to): + """Assign new field name to given location in the structure + + Parameters + ---------- + where: str | tuple[str] + location we would like to rename + to: str + new name + """ + arr = self.array + lay = ak.copy(arr.layout) + where = list(where) if isinstance(where, tuple) else [where] + parent = None + bit = lay + while where: + if getattr(bit, "contents", None): + this = bit.fields.index(where.pop(0)) + parent, bit = bit, bit.contents[this] + else: + parent, bit = bit, bit.content + parent.fields[this] = to + return self.to_output(ak.Array(lay)) + def merge(self): """Make a single complex series out of the columns of a dataframe""" if not self.is_dataframe(self._obj): diff --git a/tests/test_pandas.py b/tests/test_pandas.py index d2786ff..13ae2b4 100644 --- a/tests/test_pandas.py +++ b/tests/test_pandas.py @@ -56,3 +56,17 @@ def test_to_autoarrow(): s2 = s.ak.to_output() assert s2.tolist() == a assert "pyarrow" in str(s2.dtype) + + +def test_rename(): + a = [{"a": [{"b": {"c": 0}}] * 2}] * 3 + s = pd.Series(a) + + s2 = s.ak.rename(("a", "b"), "d") + assert s2.tolist() == [{"a": [{"d": {"c": 0}}] * 2}] * 3 + + s2 = s.ak.rename("a", "d") + assert s2.tolist() == [{"d": [{"b": {"c": 0}}] * 2}] * 3 + + s2 = s.ak.rename(("a", "b", "c"), "d") + assert s2.tolist() == [{"a": [{"b": {"d": 0}}] * 2}] * 3