-
-
Notifications
You must be signed in to change notification settings - Fork 18.4k
Make MultiIndex.get_loc raise for unhashable type #35914
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
Make MultiIndex.get_loc raise for unhashable type #35914
Conversation
@@ -2721,8 +2723,7 @@ def _maybe_to_slice(loc): | |||
mask[loc] = True | |||
return mask | |||
|
|||
if not isinstance(key, (tuple, list)): | |||
# not including list here breaks some indexing, xref #30892 |
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 it is okay to remove this comment since we're not actually checking for list here, or should it be moved? cc @jbrockmendel
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 youre right (though havent checked 30892)
@@ -2707,6 +2707,8 @@ def get_loc(self, key, method=None): | |||
"currently supported for MultiIndex" | |||
) | |||
|
|||
hash(key) |
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.
should this raise InvalidIndexError?
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.
That was my original thought, but it broke an existing test because evidently passing a singleton list with only np.nan raises the unhashable type error (it hits a line that uses this approach of trying to hash the key):
import numpy as np
import pandas as pd
idx = pd.MultiIndex.from_tuples([("a", 1), ("b", 2)])
idx.get_loc([np.nan])
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-6-40dd73c454ae> in <module>
----> 1 idx.get_loc([np.nan])
~/opt/miniconda3/envs/pandas-1.1.1/lib/python3.8/site-packages/pandas/core/indexes/multi.py in get_loc(self, key, method)
2717 lead_key, follow_key = key[:i], key[i:]
2718 start, stop = (
-> 2719 self.slice_locs(lead_key, lead_key) if lead_key else (0, len(self))
2720 )
2721
~/opt/miniconda3/envs/pandas-1.1.1/lib/python3.8/site-packages/pandas/core/indexes/multi.py in slice_locs(self, start, end, step, kind)
2578 # This function adds nothing to its parent implementation (the magic
2579 # happens in get_slice_bound method), but it adds meaningful doc.
-> 2580 return super().slice_locs(start, end, step, kind=kind)
2581
2582 def _partial_tup_index(self, tup, side="left"):
~/opt/miniconda3/envs/pandas-1.1.1/lib/python3.8/site-packages/pandas/core/indexes/base.py in slice_locs(self, start, end, step, kind)
5159 start_slice = None
5160 if start is not None:
-> 5161 start_slice = self.get_slice_bound(start, "left", kind)
5162 if start_slice is None:
5163 start_slice = 0
~/opt/miniconda3/envs/pandas-1.1.1/lib/python3.8/site-packages/pandas/core/indexes/multi.py in get_slice_bound(self, label, side, kind)
2522 if not isinstance(label, tuple):
2523 label = (label,)
-> 2524 return self._partial_tup_index(label, side=side)
2525
2526 def slice_locs(self, start=None, end=None, step=None, kind=None):
~/opt/miniconda3/envs/pandas-1.1.1/lib/python3.8/site-packages/pandas/core/indexes/multi.py in _partial_tup_index(self, tup, side)
2593 section = labs[start:end]
2594
-> 2595 if lab not in lev and not isna(lab):
2596 if not lev.is_type_compatible(lib.infer_dtype([lab], skipna=False)):
2597 raise TypeError(f"Level type mismatch: {lab}")
~/opt/miniconda3/envs/pandas-1.1.1/lib/python3.8/site-packages/pandas/core/indexes/base.py in __contains__(self, key)
4063 False
4064 """
-> 4065 hash(key)
4066 try:
4067 return key in self._engine
TypeError: unhashable type: 'list'
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.
lgtm merge on green.
@meeseeksdev backport 1.1.x |
…#36163) Co-authored-by: Daniel Saxton <[email protected]>
Co-authored-by: Jeff Reback <[email protected]>
Co-authored-by: Jeff Reback <[email protected]>
black pandas
git diff upstream/master -u -- "*.py" | flake8 --diff