Skip to content

Rename replace_axes as set_axes + update doc of rename method #147

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Mar 14, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
97 changes: 56 additions & 41 deletions larray/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

even though it is indeed the case, __setattr__ should actually not be overridden (ever since we changed __getattr__ to return axes). It might be better to fix that in a separate PR though, because most (all?) object.__setattr__ could/should be replaced.

object.__setattr__(self, 'data', data)
object.__setattr__(self, 'axes', axes)
object.__setattr__(self, 'title', title)
Expand Down Expand Up @@ -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
--------
Expand All @@ -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
Expand All @@ -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:
Expand Down Expand Up @@ -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
--------
Expand Down Expand Up @@ -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.
Expand Down Expand Up @@ -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
-------
Expand All @@ -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
Expand All @@ -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),
Expand Down
16 changes: 8 additions & 8 deletions larray/tests/test_la.py
Original file line number Diff line number Diff line change
Expand Up @@ -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. "
Expand All @@ -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):
Expand Down Expand Up @@ -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],
Expand Down Expand Up @@ -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],
Expand All @@ -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],
Expand Down