Skip to content

Commit 90c2518

Browse files
committed
REF: Move Series logic from Index._get_values_for_loc
1 parent 191557d commit 90c2518

File tree

3 files changed

+46
-21
lines changed

3 files changed

+46
-21
lines changed

pandas/core/indexes/base.py

+21-4
Original file line numberDiff line numberDiff line change
@@ -5949,6 +5949,9 @@ def get_value(self, series: Series, key):
59495949
else:
59505950
raise
59515951

5952+
if is_integer(loc):
5953+
return series._values[loc]
5954+
59525955
return self._get_values_for_loc(series, loc, key)
59535956

59545957
def _check_indexing_error(self, key):
@@ -5964,19 +5967,33 @@ def _should_fallback_to_positional(self) -> bool:
59645967
"""
59655968
return not self.holds_integer() and not self.is_boolean()
59665969

5970+
def get_loc_result_index(self, loc, key):
5971+
"""
5972+
Find the index to attach to the result of a Series.loc lookup.
5973+
5974+
Assumes `loc` is not an integer.
5975+
5976+
key is included for MultiIndex compat.
5977+
"""
5978+
return self[loc]
5979+
5980+
# TODO(2.0): remove once get_value deprecation is enforced
5981+
@final
59675982
def _get_values_for_loc(self, series: Series, loc, key):
59685983
"""
59695984
Do a positional lookup on the given Series, returning either a scalar
59705985
or a Series.
59715986
5972-
Assumes that `series.index is self`
5987+
Assumes that `series.index is self` and that `loc` is not an integer,
5988+
the result of self.get_loc(key)
59735989
59745990
key is included for MultiIndex compat.
59755991
"""
5976-
if is_integer(loc):
5977-
return series._values[loc]
5992+
new_values = series._values[loc]
59785993

5979-
return series.iloc[loc]
5994+
new_index = self.get_loc_result_index(loc, key)
5995+
new_ser = series._constructor(new_values, index=new_index, name=series.name)
5996+
return new_ser.__finalize__(series)
59805997

59815998
@final
59825999
def set_value(self, arr, key, value) -> None:

pandas/core/indexes/multi.py

+16-16
Original file line numberDiff line numberDiff line change
@@ -2597,25 +2597,16 @@ def _should_fallback_to_positional(self) -> bool:
25972597
# GH#33355
25982598
return self.levels[0]._should_fallback_to_positional
25992599

2600-
def _get_values_for_loc(self, series: Series, loc, key):
2600+
def get_loc_result_index(self, loc, key):
26012601
"""
2602-
Do a positional lookup on the given Series, returning either a scalar
2603-
or a Series.
2602+
Find the index to attach to the result of a Series.loc lookup.
26042603
2605-
Assumes that `series.index is self`
2606-
"""
2607-
new_values = series._values[loc]
2608-
if is_scalar(loc):
2609-
return new_values
2610-
2611-
if len(new_values) == 1 and not self.nlevels > 1:
2612-
# If more than one level left, we can not return a scalar
2613-
return new_values[0]
2604+
Assumes `loc` is not an integer.
26142605
2615-
new_index = self[loc]
2616-
new_index = maybe_droplevels(new_index, key)
2617-
new_ser = series._constructor(new_values, index=new_index, name=series.name)
2618-
return new_ser.__finalize__(series)
2606+
key is included for MultiIndex compat.
2607+
"""
2608+
new_index = super().get_loc_result_index(loc, key)
2609+
return maybe_droplevels(new_index, key)
26192610

26202611
def _get_indexer_strict(
26212612
self, key, axis_name: str
@@ -2922,6 +2913,15 @@ def _maybe_to_slice(loc):
29222913

29232914
if not isinstance(key, tuple):
29242915
loc = self._get_level_indexer(key, level=0)
2916+
if (
2917+
self.nlevels == 1
2918+
and isinstance(loc, slice)
2919+
and loc.stop - loc.start == 1
2920+
and loc.step is None
2921+
):
2922+
# e.g. test_multiindex_at_get_one_level
2923+
# TODO: is this the right level at which to do this check?
2924+
return loc.start
29252925
return _maybe_to_slice(loc)
29262926

29272927
keylen = len(key)

pandas/core/series.py

+9-1
Original file line numberDiff line numberDiff line change
@@ -1086,9 +1086,17 @@ def _get_value(self, label, takeable: bool = False):
10861086
if takeable:
10871087
return self._values[label]
10881088

1089+
index = self.index
1090+
10891091
# Similar to Index.get_value, but we do not fall back to positional
10901092
loc = self.index.get_loc(label)
1091-
return self.index._get_values_for_loc(self, loc, label)
1093+
res_values = self._values[loc]
1094+
if is_integer(loc):
1095+
return res_values
1096+
1097+
res_index = index.get_loc_result_index(loc, label)
1098+
result = self._constructor(res_values, index=res_index, name=self.name)
1099+
return result.__finalize__(self)
10921100

10931101
def __setitem__(self, key, value) -> None:
10941102
check_deprecated_indexers(key)

0 commit comments

Comments
 (0)