Skip to content

Commit 14e47b5

Browse files
committed
close #237: implemented LArray.equals(check_axes=False)
1 parent 83b7a07 commit 14e47b5

File tree

2 files changed

+118
-18
lines changed

2 files changed

+118
-18
lines changed

doc/source/changes/version_0_30.rst.inc

+65-1
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,71 @@
77
Backward incompatible changes
88
-----------------------------
99

10-
* backward incompatible changes
10+
* :py:obj:`LArray.equals()` now returns True for arrays even when axes are in a different order or some axes are
11+
missing on either side (but the data is constant over that axis on the other side). To get back the old behavior, use
12+
check_axes=True. Closes :issue:`237`.
13+
14+
>>> a = Axis('a=a0,a1')
15+
>>> arr1 = ndtest(a)
16+
>>> arr1
17+
a a0 a1
18+
0 1
19+
20+
Identical arrays are (still) considered equal
21+
22+
>>> arr2 = arr1.copy()
23+
>>> arr2.equals(arr1)
24+
True
25+
26+
Arrays with different labels (for the same axes), are (still) not equal
27+
28+
>>> arr3 = arr1.set_labels('a', 'a8,a9')
29+
>>> arr3
30+
a a8 a9
31+
0 1
32+
>>> arr3.equals(arr1)
33+
False
34+
35+
Arrays with the same axes but different data, are (still) not equal
36+
37+
>>> arr4 = arr1.copy()
38+
>>> arr4['a1'] = 42
39+
>>> arr4
40+
a a0 a1
41+
0 42
42+
>>> arr4.equals(arr1)
43+
False
44+
45+
Arrays with extra axes but the same data are now considered equal
46+
47+
>>> arr5 = arr1.expand('b=b0..b2')
48+
>>> arr5
49+
a\b b0 b1 b2
50+
a0 0 0 0
51+
a1 1 1 1
52+
>>> arr5.equals(arr1)
53+
True
54+
55+
Unless check_axes is True
56+
57+
>>> arr5.equals(arr1, check_axes=True)
58+
False
59+
60+
Arrays with axes in a different order (but the same data) are also equal...
61+
62+
>>> arr6 = arr5.transpose()
63+
>>> arr6
64+
b\a a0 a1
65+
b0 0 1
66+
b1 0 1
67+
b2 0 1
68+
>>> arr6.equals(arr5)
69+
True
70+
71+
Unless check_axes is True
72+
73+
>>> arr3.equals(arr4, check_axes=True)
74+
False
1175

1276

1377
New features

larray/core/array.py

+53-17
Original file line numberDiff line numberDiff line change
@@ -5081,23 +5081,27 @@ def __float__(self):
50815081
return self.data.__float__()
50825082

50835083
@deprecate_kwarg('nan_equals', 'nans_equal')
5084-
def equals(self, other, rtol=0, atol=0, nans_equal=False):
5085-
"""
5084+
def equals(self, other, rtol=0, atol=0, nans_equal=False, check_axes=False):
5085+
r"""
50865086
Compares self with another array and returns True if they have the same axes and elements, False otherwise.
50875087
50885088
Parameters
50895089
----------
5090-
other: LArray-like
5090+
other : LArray-like
50915091
Input array. aslarray() is used on a non-LArray input.
50925092
rtol : float or int, optional
50935093
The relative tolerance parameter (see Notes). Defaults to 0.
50945094
atol : float or int, optional
50955095
The absolute tolerance parameter (see Notes). Defaults to 0.
5096-
nans_equal: boolean, optional
5096+
nans_equal : boolean, optional
50975097
Whether or not to consider nan values at the same positions in the two arrays as equal.
50985098
By default, an array containing nan values is never equal to another array, even if that other array
50995099
also contains nan values at the same positions. The reason is that a nan value is different from
51005100
*anything*, including itself. Defaults to False.
5101+
check_axes : boolean, optional
5102+
Whether or not to check that the set of axes and their order is the same on both sides. Defaults to False.
5103+
If False, two arrays with compatible axes (and the same data) will compare equal, even if some axis is
5104+
missing on either side or if the axes are in a different order.
51015105
51025106
Returns
51035107
-------
@@ -5121,17 +5125,17 @@ def equals(self, other, rtol=0, atol=0, nans_equal=False):
51215125
--------
51225126
>>> arr1 = ndtest((2, 3))
51235127
>>> arr1
5124-
a\\b b0 b1 b2
5128+
a\b b0 b1 b2
51255129
a0 0 1 2
51265130
a1 3 4 5
51275131
>>> arr2 = arr1.copy()
5128-
>>> arr1.equals(arr2)
5132+
>>> arr2.equals(arr1)
51295133
True
51305134
>>> arr2['b1'] += 1
5131-
>>> arr1.equals(arr2)
5135+
>>> arr2.equals(arr1)
51325136
False
51335137
>>> arr3 = arr1.set_labels('a', ['x0', 'x1'])
5134-
>>> arr1.equals(arr3)
5138+
>>> arr3.equals(arr1)
51355139
False
51365140
51375141
Test equality between two arrays within a given tolerance range.
@@ -5145,36 +5149,68 @@ def equals(self, other, rtol=0, atol=0, nans_equal=False):
51455149
>>> arr2
51465150
a a0 a1
51475151
5.999 8.001
5148-
>>> arr1.equals(arr2)
5152+
>>> arr2.equals(arr1)
51495153
False
5150-
>>> arr1.equals(arr2, atol=0.01)
5154+
>>> arr2.equals(arr1, atol=0.01)
51515155
True
5152-
>>> arr1.equals(arr2, rtol=0.01)
5156+
>>> arr2.equals(arr1, rtol=0.01)
51535157
True
51545158
51555159
Arrays with nan values
51565160
51575161
>>> arr1 = ndtest((2, 3), dtype=float)
51585162
>>> arr1['a1', 'b1'] = nan
51595163
>>> arr1
5160-
a\\b b0 b1 b2
5164+
a\b b0 b1 b2
51615165
a0 0.0 1.0 2.0
51625166
a1 3.0 nan 5.0
51635167
>>> arr2 = arr1.copy()
51645168
>>> # By default, an array containing nan values is never equal to another array,
51655169
>>> # even if that other array also contains nan values at the same positions.
51665170
>>> # The reason is that a nan value is different from *anything*, including itself.
5167-
>>> arr1.equals(arr2)
5171+
>>> arr2.equals(arr1)
51685172
False
51695173
>>> # set flag nans_equal to True to overwrite this behavior
5170-
>>> arr1.equals(arr2, nans_equal=True)
5174+
>>> arr2.equals(arr1, nans_equal=True)
5175+
True
5176+
5177+
Arrays with the same data but different axes
5178+
5179+
>>> arr1 = ndtest((2, 2))
5180+
>>> arr1
5181+
a\b b0 b1
5182+
a0 0 1
5183+
a1 2 3
5184+
>>> arr2 = arr1.transpose()
5185+
>>> arr2
5186+
b\a a0 a1
5187+
b0 0 2
5188+
b1 1 3
5189+
>>> arr2.equals(arr1)
5190+
True
5191+
>>> arr2.equals(arr1, check_axes=True)
5192+
False
5193+
>>> arr2 = arr1.expand('c=c0,c1')
5194+
>>> arr2
5195+
a b\c c0 c1
5196+
a0 b0 0 0
5197+
a0 b1 1 1
5198+
a1 b0 2 2
5199+
a1 b1 3 3
5200+
>>> arr2.equals(arr1)
51715201
True
5202+
>>> arr2.equals(arr1, check_axes=True)
5203+
False
51725204
"""
51735205
try:
51745206
other = aslarray(other)
51755207
except Exception:
51765208
return False
5177-
return self.axes == other.axes and all(self.eq(other, rtol=rtol, atol=atol, nans_equal=nans_equal))
5209+
try:
5210+
axes_equal = self.axes == other.axes if check_axes else True
5211+
return axes_equal and all(self.eq(other, rtol=rtol, atol=atol, nans_equal=nans_equal))
5212+
except ValueError:
5213+
return False
51785214

51795215
@deprecate_kwarg('nan_equals', 'nans_equal')
51805216
def eq(self, other, rtol=0, atol=0, nans_equal=False):
@@ -5183,13 +5219,13 @@ def eq(self, other, rtol=0, atol=0, nans_equal=False):
51835219
51845220
Parameters
51855221
----------
5186-
other: LArray-like
5222+
other : LArray-like
51875223
Input array. aslarray() is used on a non-LArray input.
51885224
rtol : float or int, optional
51895225
The relative tolerance parameter (see Notes). Defaults to 0.
51905226
atol : float or int, optional
51915227
The absolute tolerance parameter (see Notes). Defaults to 0.
5192-
nans_equal: boolean, optional
5228+
nans_equal : boolean, optional
51935229
Whether or not to consider nan values at the same positions in the two arrays as equal.
51945230
By default, an array containing nan values is never equal to another array, even if that other array
51955231
also contains nan values at the same positions. The reason is that a nan value is different from

0 commit comments

Comments
 (0)