Skip to content

Commit 5d8009d

Browse files
BUG: Fix MultiIndex.at lookup with pd.NA in Int64Dtype level
1 parent 142c640 commit 5d8009d

File tree

3 files changed

+15
-0
lines changed

3 files changed

+15
-0
lines changed

doc/source/whatsnew/v3.0.0.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1132,6 +1132,7 @@ Interval
11321132

11331133
Indexing
11341134
^^^^^^^^
1135+
- Bug in :func:`pandas.concat` incorrectly constructing the :class:`MultiIndex` when an inner level contained :obj:`pandas.NA` with :class:`pandas.Int64Dtype`, causing a :exc:`KeyError` on lookup (:issue:`62903`)
11351136
- Bug in :meth:`DataFrame.__getitem__` returning modified columns when called with ``slice`` in Python 3.12 (:issue:`57500`)
11361137
- Bug in :meth:`DataFrame.__getitem__` when slicing a :class:`DataFrame` with many rows raised an ``OverflowError`` (:issue:`59531`)
11371138
- Bug in :meth:`DataFrame.__setitem__` on an empty :class:`DataFrame` with a tuple corrupting the frame (:issue:`54385`)

pandas/core/indexes/multi.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3325,6 +3325,12 @@ def _maybe_to_slice(loc):
33253325
try:
33263326
return self._engine.get_loc(key)
33273327
except KeyError as err:
3328+
if any(isna(k) for k in key):
3329+
loc, _ = self.get_loc_level(
3330+
key, range(self.nlevels), drop_level=False
3331+
)
3332+
if lib.is_integer(loc):
3333+
return loc
33283334
raise KeyError(key) from err
33293335
except TypeError:
33303336
# e.g. test_partial_slicing_with_multiindex partial string slicing

pandas/tests/indexes/multi/test_indexing.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -710,6 +710,14 @@ def test_get_loc_nan(self, level, nulls_fixture):
710710
idx = MultiIndex.from_product(levels)
711711
assert idx.get_loc(tuple(key)) == 3
712712

713+
def test_multiindex_at_lookup_with_na_key(self):
714+
index = MultiIndex(levels=[[1, 2], [2, pd.NA]], codes=[[0, 1], [0, 1]])
715+
df = DataFrame({"a": [1, 2]}, index=index)
716+
result = df.at[(2, pd.NA), "a"]
717+
assert result == 2
718+
loc_result = df.loc[(2, pd.NA), "a"]
719+
assert loc_result == 2
720+
713721
def test_get_loc_missing_nan(self):
714722
# GH 8569
715723
idx = MultiIndex.from_arrays([[1.0, 2.0], [3.0, 4.0]])

0 commit comments

Comments
 (0)