diff --git a/pandas/core/indexes/base.py b/pandas/core/indexes/base.py index 3c735fc0309b6..cb827851cc595 100644 --- a/pandas/core/indexes/base.py +++ b/pandas/core/indexes/base.py @@ -4601,7 +4601,7 @@ def get_value(self, series: "Series", key): else: raise - return self._get_values_for_loc(series, loc) + return self._get_values_for_loc(series, loc, key) def _should_fallback_to_positional(self) -> bool: """ @@ -4611,12 +4611,14 @@ def _should_fallback_to_positional(self) -> bool: return False return True - def _get_values_for_loc(self, series: "Series", loc): + def _get_values_for_loc(self, series: "Series", loc, key): """ Do a positional lookup on the given Series, returning either a scalar or a Series. Assumes that `series.index is self` + + key is included for MultiIndex compat. """ if is_integer(loc): return series._values[loc] diff --git a/pandas/core/indexes/multi.py b/pandas/core/indexes/multi.py index 708bea7d132a2..81e89441e92d8 100644 --- a/pandas/core/indexes/multi.py +++ b/pandas/core/indexes/multi.py @@ -1,5 +1,15 @@ from sys import getsizeof -from typing import Any, Hashable, Iterable, List, Optional, Sequence, Tuple, Union +from typing import ( + TYPE_CHECKING, + Any, + Hashable, + Iterable, + List, + Optional, + Sequence, + Tuple, + Union, +) import warnings import numpy as np @@ -56,6 +66,9 @@ pprint_thing, ) +if TYPE_CHECKING: + from pandas import Series # noqa:F401 + _index_doc_kwargs = dict(ibase._index_doc_kwargs) _index_doc_kwargs.update( dict(klass="MultiIndex", target_klass="MultiIndex or list of tuples") @@ -2326,28 +2339,32 @@ def get_value(self, series, key): # We have to explicitly exclude generators, as these are hashable. raise InvalidIndexError(key) - def _try_mi(k): - # TODO: what if a level contains tuples?? - loc = self.get_loc(k) - - new_values = series._values[loc] - if is_scalar(loc): - return new_values - - new_index = self[loc] - new_index = maybe_droplevels(new_index, k) - return series._constructor( - new_values, index=new_index, name=series.name - ).__finalize__(self) - try: - return _try_mi(key) + loc = self.get_loc(key) except KeyError: if is_integer(key): - return series._values[key] + loc = key else: raise + return self._get_values_for_loc(series, loc, key) + + def _get_values_for_loc(self, series: "Series", loc, key): + """ + Do a positional lookup on the given Series, returning either a scalar + or a Series. + + Assumes that `series.index is self` + """ + new_values = series._values[loc] + if is_scalar(loc): + return new_values + + new_index = self[loc] + new_index = maybe_droplevels(new_index, key) + new_ser = series._constructor(new_values, index=new_index, name=series.name) + return new_ser.__finalize__(series) + def _convert_listlike_indexer(self, keyarr): """ Parameters