From a96bc7e678e77c703f31a09965f9e5f6b9994c2d Mon Sep 17 00:00:00 2001 From: Vignesh Iyer Date: 2025年9月20日 17:06:21 -0700 Subject: [PATCH 1/6] BUG: Fix Index.get_level_values() with boolean, NaN, NA, NaT names --- doc/source/whatsnew/v3.0.0.rst | 1 + pandas/core/indexes/base.py | 22 ++++++++++++++++------ 2 files changed, 17 insertions(+), 6 deletions(-) diff --git a/doc/source/whatsnew/v3.0.0.rst b/doc/source/whatsnew/v3.0.0.rst index 9210f1e0082f0..dea4c6801227c 100644 --- a/doc/source/whatsnew/v3.0.0.rst +++ b/doc/source/whatsnew/v3.0.0.rst @@ -1143,6 +1143,7 @@ Other - Bug in :meth:`DataFrame.transform` that was returning the wrong order unless the index was monotonically increasing. (:issue:`57069`) - 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`) - 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`) +- Bug in :meth:`Index.get_level_values` incorrectly handling boolean, ``np.nan``, ``pd.NA``, and ``pd.NaT`` level names (:issue:`TBD`) - Bug in :meth:`MultiIndex.fillna` error message was referring to ``isna`` instead of ``fillna`` (:issue:`60974`) - Bug in :meth:`Series.describe` where median percentile was always included when the ``percentiles`` argument was passed (:issue:`60550`). - Bug in :meth:`Series.diff` allowing non-integer values for the ``periods`` argument. (:issue:`56607`) diff --git a/pandas/core/indexes/base.py b/pandas/core/indexes/base.py index d75479da70d11..848244ae936ac 100644 --- a/pandas/core/indexes/base.py +++ b/pandas/core/indexes/base.py @@ -38,6 +38,7 @@ is_datetime_array, no_default, ) +from pandas._libs.missing import is_matching_na from pandas._libs.tslibs import ( OutOfBoundsDatetime, Timestamp, @@ -2087,7 +2088,9 @@ def _validate_index_level(self, level) -> None: verification must be done like in MultiIndex. """ - if isinstance(level, int): + if lib.is_integer(level): + if isinstance(self.name, int) and self.name == level: + return if level < 0 and level != -1: raise IndexError( "Too many levels: Index has only 1 level, " @@ -2097,10 +2100,17 @@ def _validate_index_level(self, level) -> None: raise IndexError( f"Too many levels: Index has only 1 level, not {level + 1}" ) + mismatch_error_msg = ( + f"Requested level ({level}) does not match index name ({self.name})" + ) + if isna(level) and isna(self.name): + if not is_matching_na(level, self.name): + raise KeyError(mismatch_error_msg) + return + elif isna(level) or isna(self.name): + raise KeyError(mismatch_error_msg) elif level != self.name: - raise KeyError( - f"Requested level ({level}) does not match index name ({self.name})" - ) + raise KeyError(mismatch_error_msg) def _get_level_number(self, level) -> int: self._validate_index_level(level) @@ -3069,7 +3079,7 @@ def union(self, other, sort: bool | None = None): """ self._validate_sort_keyword(sort) self._assert_can_do_setop(other) - other, result_name = self._convert_can_do_setop(other) + other, _result_name = self._convert_can_do_setop(other) if self.dtype != other.dtype: if ( @@ -6079,7 +6089,7 @@ def _get_indexer_strict(self, key, axis_name: str_t) -> tuple[Index, np.ndarray] indexer = self.get_indexer_for(keyarr) keyarr = self.reindex(keyarr)[0] else: - keyarr, indexer, new_indexer = self._reindex_non_unique(keyarr) + keyarr, indexer, _new_indexer = self._reindex_non_unique(keyarr) self._raise_if_missing(keyarr, indexer, axis_name) From 46e166b71ceb1be2d1a5acb8c95644497cf83e72 Mon Sep 17 00:00:00 2001 From: Vignesh Iyer Date: 2025年9月21日 14:40:07 -0700 Subject: [PATCH 2/6] BUG: Fix return statement in Index.get_level_values() for handling level 0 & -1 --- pandas/core/indexes/base.py | 1 + 1 file changed, 1 insertion(+) diff --git a/pandas/core/indexes/base.py b/pandas/core/indexes/base.py index 848244ae936ac..f305ea4a35036 100644 --- a/pandas/core/indexes/base.py +++ b/pandas/core/indexes/base.py @@ -2100,6 +2100,7 @@ def _validate_index_level(self, level) -> None: raise IndexError( f"Too many levels: Index has only 1 level, not {level + 1}" ) + return mismatch_error_msg = ( f"Requested level ({level}) does not match index name ({self.name})" ) From 55eba1386a66bbacb6b133f6d64912ec0275d9df Mon Sep 17 00:00:00 2001 From: Vignesh Iyer Date: 2025年9月21日 19:39:36 -0700 Subject: [PATCH 3/6] FIX: Revert unrelated variable renaming changes --- pandas/core/indexes/base.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pandas/core/indexes/base.py b/pandas/core/indexes/base.py index f305ea4a35036..c4318c1988934 100644 --- a/pandas/core/indexes/base.py +++ b/pandas/core/indexes/base.py @@ -3080,7 +3080,7 @@ def union(self, other, sort: bool | None = None): """ self._validate_sort_keyword(sort) self._assert_can_do_setop(other) - other, _result_name = self._convert_can_do_setop(other) + other, result_name = self._convert_can_do_setop(other) if self.dtype != other.dtype: if ( @@ -6090,7 +6090,7 @@ def _get_indexer_strict(self, key, axis_name: str_t) -> tuple[Index, np.ndarray] indexer = self.get_indexer_for(keyarr) keyarr = self.reindex(keyarr)[0] else: - keyarr, indexer, _new_indexer = self._reindex_non_unique(keyarr) + keyarr, indexer, new_indexer = self._reindex_non_unique(keyarr) self._raise_if_missing(keyarr, indexer, axis_name) From 1120f5973a9586e341154fed5ff621d3b7e43561 Mon Sep 17 00:00:00 2001 From: Vignesh Iyer Date: 2025年9月23日 11:57:31 -0700 Subject: [PATCH 4/6] BUG: Improve error handling in Index class for level mismatch --- pandas/core/indexes/base.py | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/pandas/core/indexes/base.py b/pandas/core/indexes/base.py index c4318c1988934..04210922b03f0 100644 --- a/pandas/core/indexes/base.py +++ b/pandas/core/indexes/base.py @@ -2088,9 +2088,14 @@ def _validate_index_level(self, level) -> None: verification must be done like in MultiIndex. """ + mismatch_error_msg = ( + f"Requested level ({level}) does not match index name ({self.name})" + ) if lib.is_integer(level): - if isinstance(self.name, int) and self.name == level: + if lib.is_integer(self.name) and self.name == level: return + if lib.is_integer(self.name): + raise KeyError(mismatch_error_msg) if level < 0 and level != -1: raise IndexError( "Too many levels: Index has only 1 level, " @@ -2101,9 +2106,6 @@ def _validate_index_level(self, level) -> None: f"Too many levels: Index has only 1 level, not {level + 1}" ) return - mismatch_error_msg = ( - f"Requested level ({level}) does not match index name ({self.name})" - ) if isna(level) and isna(self.name): if not is_matching_na(level, self.name): raise KeyError(mismatch_error_msg) From c1adf30df440e0bb9c20f4e1422519f958546ef7 Mon Sep 17 00:00:00 2001 From: Vignesh Iyer Date: 2025年9月23日 14:15:11 -0700 Subject: [PATCH 5/6] FIX: Refactor error handling in Index class to ensure accurate level mismatch reporting --- pandas/core/indexes/base.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/pandas/core/indexes/base.py b/pandas/core/indexes/base.py index 04210922b03f0..8d3e9d4b94af3 100644 --- a/pandas/core/indexes/base.py +++ b/pandas/core/indexes/base.py @@ -2088,14 +2088,9 @@ def _validate_index_level(self, level) -> None: verification must be done like in MultiIndex. """ - mismatch_error_msg = ( - f"Requested level ({level}) does not match index name ({self.name})" - ) if lib.is_integer(level): if lib.is_integer(self.name) and self.name == level: return - if lib.is_integer(self.name): - raise KeyError(mismatch_error_msg) if level < 0 and level != -1: raise IndexError( "Too many levels: Index has only 1 level, " @@ -2106,6 +2101,11 @@ def _validate_index_level(self, level) -> None: f"Too many levels: Index has only 1 level, not {level + 1}" ) return + mismatch_error_msg = ( + f"Requested level ({level}) does not match index name ({self.name})" + ) + if lib.is_integer(self.name): + raise KeyError(mismatch_error_msg) if isna(level) and isna(self.name): if not is_matching_na(level, self.name): raise KeyError(mismatch_error_msg) From a60c3b87623940449ac50f0523f0c9c72ff90a26 Mon Sep 17 00:00:00 2001 From: Vignesh Iyer Date: 2025年9月23日 20:49:54 -0700 Subject: [PATCH 6/6] DOC: Correct isdigit method in StringMethods to accurately identify numeric characters --- pandas/core/strings/accessor.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pandas/core/strings/accessor.py b/pandas/core/strings/accessor.py index 21e6e2efbe778..9851975f3ae02 100644 --- a/pandas/core/strings/accessor.py +++ b/pandas/core/strings/accessor.py @@ -3610,8 +3610,8 @@ def casefold(self): >>> s3 = pd.Series(['23', '3', '1⁄5', '']) >>> s3.str.isdigit() 0 True - 1 False - 2 False + 1 True + 2 True 3 False dtype: bool """

AltStyle によって変換されたページ (->オリジナル) /