Skip to content

Commit b5d5dca

Browse files
committed
operator equal on Index should behavior similarly to Series
1 parent 799048a commit b5d5dca

File tree

3 files changed

+50
-54
lines changed

3 files changed

+50
-54
lines changed

doc/source/whatsnew/v0.16.1.txt

+1-1
Original file line numberDiff line numberDiff line change
@@ -197,7 +197,7 @@ Bug Fixes
197197
- Fixed bug where ``DataFrame.plot()`` raised an error when both ``color`` and ``style`` keywords were passed and there was no color symbol in the style strings (:issue:`9671`)
198198
- Bug in ``read_csv`` and ``read_table`` when using ``skip_rows`` parameter if blank lines are present. (:issue:`9832`)
199199
- Bug in ``read_csv()`` interprets ``index_col=True`` as ``1`` (:issue:`9798`)
200-
- Bug in index equality comparisons using ``==`` failing on Index/MultiIndex type incompatibility (:issue:`9785`)
200+
- Bug in index equality comparisons using ``==`` failing on Index/MultiIndex type incompatibility (:issue:`9785`, :issue:`9947`)
201201
- Bug in which ``SparseDataFrame`` could not take `nan` as a column name (:issue:`8822`)
202202
- Bug in ``to_msgpack`` and ``read_msgpack`` zlib and blosc compression support (:issue:`9783`)
203203

pandas/core/index.py

+4
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ def _try_get_item(x):
4545
except AttributeError:
4646
return x
4747

48+
4849
class InvalidIndexError(Exception):
4950
pass
5051

@@ -2448,6 +2449,9 @@ def _add_comparison_methods(cls):
24482449
def _make_compare(op):
24492450

24502451
def _evaluate_compare(self, other):
2452+
if isinstance(other, (np.ndarray, Index)):
2453+
if other.ndim > 0 and len(self) != len(other):
2454+
raise ValueError('Lengths must match to compare')
24512455
func = getattr(self.values, op)
24522456
result = func(np.asarray(other))
24532457

pandas/tests/test_index.py

+45-53
Original file line numberDiff line numberDiff line change
@@ -1372,22 +1372,51 @@ def test_groupby(self):
13721372
tm.assert_dict_equal(groups, exp)
13731373

13741374
def test_equals_op(self):
1375-
# For issue #9785
1375+
# GH9947
13761376
index_a = Index(['foo', 'bar', 'baz'])
13771377
index_b = Index(['foo', 'bar', 'baz', 'qux'])
1378-
# Testing Numpy Results Equivelent
1379-
assert_array_equal(
1380-
index_a.equals(index_a),
1381-
index_a == index_a
1382-
)
1383-
assert_array_equal(
1384-
index_a.equals(index_b),
1385-
index_a == index_b,
1386-
)
1387-
assert_array_equal(
1388-
index_b.equals(index_a),
1389-
index_b == index_a,
1390-
)
1378+
index_c = Index(['foo', 'bar', 'qux'])
1379+
1380+
with tm.assertRaisesRegexp(ValueError, "Lengths must match"):
1381+
index_a == index_b
1382+
assert_array_equal(index_a == index_a, np.array([True, True, True]))
1383+
assert_array_equal(index_a == index_c, np.array([True, True, False]))
1384+
1385+
# test comparisons with numpy arrays
1386+
array_a = np.array(['foo', 'bar', 'baz'])
1387+
array_b = np.array(['foo', 'bar', 'baz', 'qux'])
1388+
array_c = np.array(['foo', 'bar', 'qux'])
1389+
with tm.assertRaisesRegexp(ValueError, "Lengths must match"):
1390+
index_a == array_b
1391+
assert_array_equal(index_a == array_a, np.array([True, True, True]))
1392+
assert_array_equal(index_a == array_c, np.array([True, True, False]))
1393+
1394+
# test comparisons with Series
1395+
series_a = Series(['foo', 'bar', 'baz'])
1396+
series_b = Series(['foo', 'bar', 'baz', 'qux'])
1397+
series_c = Series(['foo', 'bar', 'qux'])
1398+
with tm.assertRaisesRegexp(ValueError, "Lengths must match"):
1399+
index_a == series_b
1400+
assert_array_equal(index_a == series_a, np.array([True, True, True]))
1401+
assert_array_equal(index_a == series_c, np.array([True, True, False]))
1402+
1403+
# GH9785
1404+
# test comparisons of multiindex
1405+
from pandas.compat import StringIO
1406+
df = pd.read_csv(StringIO('a,b,c\n1,2,3\n4,5,6'), index_col=[0, 1])
1407+
assert_array_equal(df.index == df.index, np.array([True, True]))
1408+
1409+
mi1 = MultiIndex.from_tuples([(1, 2), (4, 5)])
1410+
assert_array_equal(df.index == mi1, np.array([True, True]))
1411+
mi2 = MultiIndex.from_tuples([(1, 2), (4, 6)])
1412+
assert_array_equal(df.index == mi2, np.array([True, False]))
1413+
mi3 = MultiIndex.from_tuples([(1, 2), (4, 5), (8, 9)])
1414+
with tm.assertRaisesRegexp(ValueError, "Lengths must match"):
1415+
df.index == mi3
1416+
with tm.assertRaisesRegexp(ValueError, "Lengths must match"):
1417+
df.index == index_a
1418+
assert_array_equal(index_a == mi3, np.array([False, False, False]))
1419+
13911420

13921421
class TestCategoricalIndex(Base, tm.TestCase):
13931422
_holder = CategoricalIndex
@@ -1736,6 +1765,7 @@ def test_equals(self):
17361765
self.assertFalse(CategoricalIndex(list('aabca') + [np.nan],categories=['c','a','b',np.nan]).equals(list('aabca')))
17371766
self.assertTrue(CategoricalIndex(list('aabca') + [np.nan],categories=['c','a','b',np.nan]).equals(list('aabca') + [np.nan]))
17381767

1768+
17391769
class Numeric(Base):
17401770

17411771
def test_numeric_compat(self):
@@ -4504,47 +4534,9 @@ def test_index_name_retained(self):
45044534
tm.assert_frame_equal(result, df_expected)
45054535

45064536
def test_equals_operator(self):
4507-
# For issue #9785
4537+
# GH9785
45084538
self.assertTrue((self.index == self.index).all())
45094539

4510-
def test_index_compare(self):
4511-
# For issue #9785
4512-
index_unequal = Index(['foo', 'bar', 'baz'])
4513-
index_equal = Index([
4514-
('foo', 'one'), ('foo', 'two'), ('bar', 'one'),
4515-
('baz', 'two'), ('qux', 'one'), ('qux', 'two')
4516-
], tupleize_cols=False)
4517-
# Testing Numpy Results Equivelent
4518-
assert_array_equal(
4519-
index_unequal.equals(self.index),
4520-
index_unequal == self.index,
4521-
err_msg = 'Index compared with MultiIndex failed',
4522-
)
4523-
assert_array_equal(
4524-
self.index.equals(index_unequal),
4525-
self.index == index_unequal,
4526-
err_msg = 'MultiIndex compared with Index failed',
4527-
)
4528-
assert_array_equal(
4529-
self.index.equals(index_equal),
4530-
self.index == index_equal,
4531-
err_msg = 'MultiIndex compared with Similar Index failed',
4532-
)
4533-
assert_array_equal(
4534-
index_equal.equals(self.index),
4535-
index_equal == self.index,
4536-
err_msg = 'Index compared with Similar MultiIndex failed',
4537-
)
4538-
# Testing that the result is true for the index_equal case
4539-
self.assertTrue(
4540-
(self.index == index_equal).all(),
4541-
msg='Assert Index compared with Similar MultiIndex match'
4542-
)
4543-
self.assertTrue(
4544-
(index_equal == self.index).all(),
4545-
msg='Assert MultiIndex compared with Similar Index match'
4546-
)
4547-
45484540

45494541
def test_get_combined_index():
45504542
from pandas.core.index import _get_combined_index

0 commit comments

Comments
 (0)