Skip to content

Commit 0556613

Browse files
authored
BUG: MultiIndex.equals returning incorrectly True when Indexes contains NaN (#38511)
1 parent a66482e commit 0556613

File tree

3 files changed

+18
-4
lines changed

3 files changed

+18
-4
lines changed

doc/source/whatsnew/v1.3.0.rst

+1-1
Original file line numberDiff line numberDiff line change
@@ -232,7 +232,7 @@ MultiIndex
232232
^^^^^^^^^^
233233

234234
- Bug in :meth:`DataFrame.drop` raising ``TypeError`` when :class:`MultiIndex` is non-unique and no level is provided (:issue:`36293`)
235-
-
235+
- Bug in :meth:`MultiIndex.equals` incorrectly returning ``True`` when :class:`MultiIndex` containing ``NaN`` even when they are differntly ordered (:issue:`38439`)
236236

237237
I/O
238238
^^^

pandas/core/indexes/multi.py

+7-3
Original file line numberDiff line numberDiff line change
@@ -3454,13 +3454,17 @@ def equals(self, other: object) -> bool:
34543454

34553455
for i in range(self.nlevels):
34563456
self_codes = self.codes[i]
3457-
self_codes = self_codes[self_codes != -1]
3457+
other_codes = other.codes[i]
3458+
self_mask = self_codes == -1
3459+
other_mask = other_codes == -1
3460+
if not np.array_equal(self_mask, other_mask):
3461+
return False
3462+
self_codes = self_codes[~self_mask]
34583463
self_values = algos.take_nd(
34593464
np.asarray(self.levels[i]._values), self_codes, allow_fill=False
34603465
)
34613466

3462-
other_codes = other.codes[i]
3463-
other_codes = other_codes[other_codes != -1]
3467+
other_codes = other_codes[~other_mask]
34643468
other_values = algos.take_nd(
34653469
np.asarray(other.levels[i]._values), other_codes, allow_fill=False
34663470
)

pandas/tests/indexes/multi/test_equivalence.py

+10
Original file line numberDiff line numberDiff line change
@@ -209,6 +209,16 @@ def test_equals_missing_values():
209209
assert not result
210210

211211

212+
def test_equals_missing_values_differently_sorted():
213+
# GH#38439
214+
mi1 = pd.MultiIndex.from_tuples([(81.0, np.nan), (np.nan, np.nan)])
215+
mi2 = pd.MultiIndex.from_tuples([(np.nan, np.nan), (81.0, np.nan)])
216+
assert not mi1.equals(mi2)
217+
218+
mi2 = pd.MultiIndex.from_tuples([(81.0, np.nan), (np.nan, np.nan)])
219+
assert mi1.equals(mi2)
220+
221+
212222
def test_is_():
213223
mi = MultiIndex.from_tuples(zip(range(10), range(10)))
214224
assert mi.is_(mi)

0 commit comments

Comments
 (0)