Skip to content

Commit a96bc7e

Browse files
committed
BUG: Fix Index.get_level_values() with boolean, NaN, NA, NaT names
1 parent 08d21d7 commit a96bc7e

File tree

2 files changed

+17
-6
lines changed

2 files changed

+17
-6
lines changed

doc/source/whatsnew/v3.0.0.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1143,6 +1143,7 @@ Other
11431143
- Bug in :meth:`DataFrame.transform` that was returning the wrong order unless the index was monotonically increasing. (:issue:`57069`)
11441144
- Bug in :meth:`DataFrame.where` where using a non-bool type array in the function would return a ``ValueError`` instead of a ``TypeError`` (:issue:`56330`)
11451145
- Bug in :meth:`Index.sort_values` when passing a key function that turns values into tuples, e.g. ``key=natsort.natsort_key``, would raise ``TypeError`` (:issue:`56081`)
1146+
- Bug in :meth:`Index.get_level_values` incorrectly handling boolean, ``np.nan``, ``pd.NA``, and ``pd.NaT`` level names (:issue:`TBD`)
11461147
- Bug in :meth:`MultiIndex.fillna` error message was referring to ``isna`` instead of ``fillna`` (:issue:`60974`)
11471148
- Bug in :meth:`Series.describe` where median percentile was always included when the ``percentiles`` argument was passed (:issue:`60550`).
11481149
- Bug in :meth:`Series.diff` allowing non-integer values for the ``periods`` argument. (:issue:`56607`)

pandas/core/indexes/base.py

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@
3838
is_datetime_array,
3939
no_default,
4040
)
41+
from pandas._libs.missing import is_matching_na
4142
from pandas._libs.tslibs import (
4243
OutOfBoundsDatetime,
4344
Timestamp,
@@ -2087,7 +2088,9 @@ def _validate_index_level(self, level) -> None:
20872088
verification must be done like in MultiIndex.
20882089
20892090
"""
2090-
if isinstance(level, int):
2091+
if lib.is_integer(level):
2092+
if isinstance(self.name, int) and self.name == level:
2093+
return
20912094
if level < 0 and level != -1:
20922095
raise IndexError(
20932096
"Too many levels: Index has only 1 level, "
@@ -2097,10 +2100,17 @@ def _validate_index_level(self, level) -> None:
20972100
raise IndexError(
20982101
f"Too many levels: Index has only 1 level, not {level + 1}"
20992102
)
2103+
mismatch_error_msg = (
2104+
f"Requested level ({level}) does not match index name ({self.name})"
2105+
)
2106+
if isna(level) and isna(self.name):
2107+
if not is_matching_na(level, self.name):
2108+
raise KeyError(mismatch_error_msg)
2109+
return
2110+
elif isna(level) or isna(self.name):
2111+
raise KeyError(mismatch_error_msg)
21002112
elif level != self.name:
2101-
raise KeyError(
2102-
f"Requested level ({level}) does not match index name ({self.name})"
2103-
)
2113+
raise KeyError(mismatch_error_msg)
21042114

21052115
def _get_level_number(self, level) -> int:
21062116
self._validate_index_level(level)
@@ -3069,7 +3079,7 @@ def union(self, other, sort: bool | None = None):
30693079
"""
30703080
self._validate_sort_keyword(sort)
30713081
self._assert_can_do_setop(other)
3072-
other, result_name = self._convert_can_do_setop(other)
3082+
other, _result_name = self._convert_can_do_setop(other)
30733083

30743084
if self.dtype != other.dtype:
30753085
if (
@@ -6079,7 +6089,7 @@ def _get_indexer_strict(self, key, axis_name: str_t) -> tuple[Index, np.ndarray]
60796089
indexer = self.get_indexer_for(keyarr)
60806090
keyarr = self.reindex(keyarr)[0]
60816091
else:
6082-
keyarr, indexer, new_indexer = self._reindex_non_unique(keyarr)
6092+
keyarr, indexer, _new_indexer = self._reindex_non_unique(keyarr)
60836093

60846094
self._raise_if_missing(keyarr, indexer, axis_name)
60856095

0 commit comments

Comments
 (0)