From a139f9952a0558a365613d8c9388ed6eec7b26f5 Mon Sep 17 00:00:00 2001 From: Alix Damman Date: Mon, 13 Mar 2017 14:20:09 +0100 Subject: [PATCH] fix #121 : Update docstring of set_labels. fix #133 :Rename replace_axes as set_axes. Add inplace flag to set_axes and rename methods --- larray/core.py | 97 ++++++++++++++++++++++++----------------- larray/tests/test_la.py | 16 +++---- 2 files changed, 64 insertions(+), 49 deletions(-) diff --git a/larray/core.py b/larray/core.py index bd28bce1e..003a97009 100644 --- a/larray/core.py +++ b/larray/core.py @@ -3905,7 +3905,7 @@ def __init__(self, raise ValueError("length of axes %s does not match " "data shape %s" % (axes.shape, data.shape)) - # Because __getattr__ and __setattr__ have been rewritten + # Because __getattr__ and __setattr__ have been overridden object.__setattr__(self, 'data', data) object.__setattr__(self, 'axes', axes) object.__setattr__(self, 'title', title) @@ -3937,31 +3937,28 @@ def nonzero(self): # can do a[a.nonzero()] return self.data.nonzero() - def replace_axes(self, axes_to_replace=None, new_axis=None, **kwargs): + def set_axes(self, axes_to_replace=None, new_axis=None, inplace=False, **kwargs): """ - Returns an array with one or several axes replaced. + Replace one, several or all axes of the array. Parameters ---------- - axes_to_replace : axis ref or dict {axis ref: axis} or - list of tuple (axis ref, axis) or list of Axis or - AxisCollection - Axes to replace. If a single axis reference is given, - the `new_axes` argument must be used. If a list of - Axis or an AxisCollection is given, all axes will be - replaced by the new ones. In that case, the number of - new axes must match the number of the old ones. + axes_to_replace : axis ref or dict {axis ref: axis} or list of tuple (axis ref, axis) + or list of Axis or AxisCollection + Axes to replace. If a single axis reference is given, the `new_axiss` argument must be provided. + If a list of Axis or an AxisCollection is given, all axes will be replaced by the new ones. + In that case, the number of new axes must match the number of the old ones. new_axis : Axis - New axis if `axes_to_replace` - contains a single axis reference. + New axis if `axes_to_replace` contains a single axis reference. + inplace : bool + Whether or not to modify the original object or return a new array and leave the original intact. **kwargs : Axis - New axis for each axis to replace given - as a keyword argument. + New axis for each axis to replace given as a keyword argument. Returns ------- LArray - Array with some axes replaced. + Array with axes replaced. See Also -------- @@ -3976,28 +3973,37 @@ def replace_axes(self, axes_to_replace=None, new_axis=None, **kwargs): a1 | 3 | 4 | 5 >>> row = Axis('row', ['r0', 'r1']) >>> column = Axis('column', ['c0', 'c1', 'c2']) - >>> arr.replace_axes(x.a, row) + + Replace one axis (second argument `new_axis` must be provided) + + >>> arr.set_axes(x.a, row) row\\b | b0 | b1 | b2 r0 | 0 | 1 | 2 r1 | 3 | 4 | 5 - >>> arr.replace_axes([row, column]) + + Replace several axes (keywords, list of tuple or dictionary) + + >>> arr.set_axes(a=row, b=column) row\\column | c0 | c1 | c2 r0 | 0 | 1 | 2 r1 | 3 | 4 | 5 - >>> arr.replace_axes(a=row, b=column) + >>> arr.set_axes([(x.a, row), (x.b, column)]) row\\column | c0 | c1 | c2 r0 | 0 | 1 | 2 r1 | 3 | 4 | 5 - >>> arr.replace_axes([(x.a, row), (x.b, column)]) + >>> arr.set_axes({x.a: row, x.b: column}) row\\column | c0 | c1 | c2 r0 | 0 | 1 | 2 r1 | 3 | 4 | 5 - >>> arr.replace_axes({x.a: row, x.b: column}) + + Replace all axes (list of axes or AxisCollection) + + >>> arr.set_axes([row, column]) row\\column | c0 | c1 | c2 r0 | 0 | 1 | 2 r1 | 3 | 4 | 5 >>> arr2 = ndrange([row, column]) - >>> arr.replace_axes(arr2.axes) + >>> arr.set_axes(arr2.axes) row\\column | c0 | c1 | c2 r0 | 0 | 1 | 2 r1 | 3 | 4 | 5 @@ -4021,13 +4027,17 @@ def replace_axes(self, axes_to_replace=None, new_axis=None, **kwargs): items += kwargs.items() for old, new in items: axes = axes.replace(old, new) - return LArray(self.data, axes, title=self.title) + if inplace: + object.__setattr__(self, 'axes', axes) + return self + else: + return LArray(self.data, axes, title=self.title) def with_axes(self, axes): warnings.warn("LArray.with_axes is deprecated, " "use LArray.replace_axes instead", DeprecationWarning) - return self.replace_axes(axes) + return self.set_axes(axes) def __getattr__(self, key): try: @@ -4271,28 +4281,27 @@ def __bool__(self): # Python 2 __nonzero__= __bool__ - def rename(self, renames=None, to=None, **kwargs): - """Renames some array axes. + def rename(self, renames=None, to=None, inplace=False, **kwargs): + """Renames axes of the array. Parameters ---------- renames : axis ref or dict {axis ref: str} or list of tuple (axis ref, str) - Renames to apply. If a single axis reference - is given, the `to` argument must be used. - to : str or Axis - New name if `renames` contains a single axis reference - **kwargs : str + Renames to apply. If a single axis reference is given, the `to` argument must be used. + to : string or Axis + New name if `renames` contains a single axis reference. + **kwargs : New name for each axis given as a keyword argument. Returns ------- LArray - Array with some axes renamed. + Array with axes renamed. See Also -------- - replace_axes : replace one or several axes + set_axes : replace one or several axes Examples -------- @@ -4332,7 +4341,11 @@ def rename(self, renames=None, to=None, **kwargs): renames = {self.axes[k]: v for k, v in items} axes = [a.rename(renames[a]) if a in renames else a for a in self.axes] - return LArray(self.data, axes) + if inplace: + object.__setattr__(self, 'axes', AxisCollection(axes)) + return self + else: + return LArray(self.data, axes) def sort_values(self, key): """Sorts values of the array. @@ -8657,13 +8670,12 @@ def set_labels(self, axis, labels, inplace=False): Parameters ---------- - axis + axis : string or Axis Axis for which we want to replace the labels. - labels : list of axis labels - New labels. + labels : int or iterable + Integer or list of values usable as the collection of labels for an Axis. inplace : bool - Whether or not to modify the original object or return a new - array and leave the original intact. + Whether or not to modify the original object or return a new array and leave the original intact. Returns ------- @@ -8677,6 +8689,10 @@ def set_labels(self, axis, labels, inplace=False): nat\\sex | M | F BE | 0 | 1 FO | 2 | 3 + >>> a.set_labels(x.sex, 'Men,Women') + nat\\sex | Men | Women + BE | 0 | 1 + FO | 2 | 3 >>> a.set_labels(x.sex, ['Men', 'Women']) nat\\sex | Men | Women BE | 0 | 1 @@ -8687,8 +8703,7 @@ def set_labels(self, axis, labels, inplace=False): axis.labels = labels return self else: - return LArray(self.data, - self.axes.replace(axis, Axis(axis.name, labels))) + return LArray(self.data, self.axes.replace(axis, Axis(axis.name, labels))) def astype(self, dtype, order='K', casting='unsafe', subok=True, copy=True): return LArray(self.data.astype(dtype, order, casting, subok, copy), diff --git a/larray/tests/test_la.py b/larray/tests/test_la.py index 1cba2ed46..6946bc261 100644 --- a/larray/tests/test_la.py +++ b/larray/tests/test_la.py @@ -2847,7 +2847,7 @@ def test_replace_axes(self): la = LArray(self.small_data, axes=(self.sex, lipro2), title=self.small_title) # replace one axis - la2 = self.small.replace_axes(x.lipro, lipro2) + la2 = self.small.set_axes(x.lipro, lipro2) assert_array_equal(la, la2) self.assertEqual(la.title, la2.title, "title of array returned by " "replace_axes should be the same as the original one. " @@ -2856,16 +2856,16 @@ def test_replace_axes(self): la = LArray(self.small_data, axes=(sex2, lipro2), title=self.small_title) # all at once - la2 = self.small.replace_axes([sex2, lipro2]) + la2 = self.small.set_axes([sex2, lipro2]) assert_array_equal(la, la2) # using keywrods args - la2 = self.small.replace_axes(sex=sex2, lipro=lipro2) + la2 = self.small.set_axes(sex=sex2, lipro=lipro2) assert_array_equal(la, la2) # using dict - la2 = self.small.replace_axes({x.sex: sex2, x.lipro: lipro2}) + la2 = self.small.set_axes({x.sex: sex2, x.lipro: lipro2}) assert_array_equal(la, la2) # using list of pairs (axis_to_replace, new_axis) - la2 = self.small.replace_axes([(x.sex, sex2), (x.lipro, lipro2)]) + la2 = self.small.set_axes([(x.sex, sex2), (x.lipro, lipro2)]) assert_array_equal(la, la2) def test_append(self): @@ -3618,7 +3618,7 @@ def test_matmul(self): f = Axis('f', 'f0,f1') # 4D(a, b, c, d) @ 3D(e, d, f) -> 5D(a, b, e, c, f) - arr3d = arr3d.replace_axes([e, d, f]) + arr3d = arr3d.set_axes([e, d, f]) res = from_lists([['a', 'b', 'e', 'c\\f', 'f0', 'f1'], ['a0', 'b0', 'e0', 'c0', 2, 3], ['a0', 'b0', 'e0', 'c1', 6, 11], @@ -3659,7 +3659,7 @@ def test_matmul(self): assert_array_equal(arr3d.__matmul__(arr4d), res) # 4D(a, b, c, d) @ 3D(b, d, f) -> 4D(a, b, c, f) - arr3d = arr3d.replace_axes([b, d, f]) + arr3d = arr3d.set_axes([b, d, f]) res = from_lists([['a', 'b', 'c\\f', 'f0', 'f1'], ['a0', 'b0', 'c0', 2, 3], ['a0', 'b0', 'c1', 6, 11], @@ -3684,7 +3684,7 @@ def test_matmul(self): assert_array_equal(arr3d.__matmul__(arr4d), res) # 4D(a, b, c, d) @ 2D(d, f) -> 5D(a, b, c, f) - arr2d = arr2d.replace_axes([d, f]) + arr2d = arr2d.set_axes([d, f]) res = from_lists([['a', 'b', 'c\\f', 'f0', 'f1'], ['a0', 'b0', 'c0', 2, 3], ['a0', 'b0', 'c1', 6, 11],