-
-
Notifications
You must be signed in to change notification settings - Fork 18.9k
BUG: Fix Index.get_level_values() mishandling of boolean, pd.NA, np.nan, and pd.NaT levels #62175
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This solves the boolean case, but it will have the same problems for the NA
, nan
and NaT
and perhaps other edge cases.
I think that its best for one of the pandas core members decide on how non-string level and Index.name should be handled.
pandas/core/indexes/base.py
Outdated
@@ -2084,7 +2084,7 @@ def _validate_index_level(self, level) -> None: | |||
verification must be done like in MultiIndex. | |||
|
|||
""" | |||
if isinstance(level, int): | |||
if type(level) is int: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just a simple edge case where the Index.name is also an int
if type(level) is int: | |
if type(level) is int: | |
if isinstance(self.name, int) and level == self.name: | |
return |
raise KeyError( | ||
f"Requested level ({level}) does not match index name ({self.name})" | ||
) | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think that this is a better verification that validates what is expected from the documentation.
elif isinstance(level, str) and isinstance(self.name, str) and level != self.name: | |
raise KeyError( | |
f"Requested level ({level}) does not match index name ({self.name})" | |
) |
pandas/core/indexes/base.py
Outdated
@@ -2084,7 +2084,10 @@ def _validate_index_level(self, level) -> None: | |||
verification must be done like in MultiIndex. | |||
|
|||
""" | |||
if isinstance(level, int): | |||
if type(level) is int: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
lib.is_integer
…d improve error messaging
…enhance error handling for boolean levels
@jbrockmendel Can you explain why these checks are constantly failing? Am I overlooking something? |
…el and index name
pandas/_libs/__init__.py
Outdated
@@ -16,6 +17,7 @@ | |||
import pandas._libs.pandas_parser # isort: skip # type: ignore[reportUnusedImport] | |||
import pandas._libs.pandas_datetime # noqa: F401 # isort: skip # type: ignore[reportUnusedImport] | |||
from pandas._libs.interval import Interval | |||
from pandas._libs.missing import NA |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
seems this change is unrelated to the rest of the PR?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, actually, I was trying something and forgot to undo this change. It's fixed in the latest commit.
pandas/core/indexes/base.py
Outdated
if isinstance(level, int): | ||
# Explicitly raise for missing/null values to match pandas convention | ||
# Also reject all NA-like values (np.nan, pd.NA, pd.NaT, etc.) | ||
if isna(level): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
what if index.name is a na-like scalar?
pandas/core/indexes/base.py
Outdated
) | ||
|
||
# Reject booleans unless the index name is actually a boolean and matches | ||
if isinstance(level, bool): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
isnt this handled in the existing elif level != self.name
check?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Makes sense... I'll keep the same.
It's really common to have level=name=None, which is getting caught by the isna(level) check you added. |
… improve error messaging
…alues and streamline error messaging
level
correctly #62169