diff --git a/pandas/core/indexes/base.py b/pandas/core/indexes/base.py index bb893bd2ffef6..c856d7d8f0dd8 100644 --- a/pandas/core/indexes/base.py +++ b/pandas/core/indexes/base.py @@ -4621,34 +4621,31 @@ def argsort(self, *args, **kwargs): @Appender(_index_shared_docs["get_value"] % _index_doc_kwargs) def get_value(self, series, key): + if not is_scalar(key): + # if key is not a scalar, directly raise an error (the code below + # would convert to numpy arrays and raise later any way) - GH29926 + raise InvalidIndexError(key) + # if we have something that is Index-like, then # use this, e.g. DatetimeIndex # Things like `Series._get_value` (via .at) pass the EA directly here. s = extract_array(series, extract_numpy=True) if isinstance(s, ExtensionArray): - if is_scalar(key): - # GH 20882, 21257 - # First try to convert the key to a location - # If that fails, raise a KeyError if an integer - # index, otherwise, see if key is an integer, and - # try that - try: - iloc = self.get_loc(key) - return s[iloc] - except KeyError: - if len(self) > 0 and (self.holds_integer() or self.is_boolean()): - raise - elif is_integer(key): - return s[key] - else: - # if key is not a scalar, directly raise an error (the code below - # would convert to numpy arrays and raise later any way) - GH29926 - raise InvalidIndexError(key) - - s = com.values_from_object(series) - k = com.values_from_object(key) + # GH 20882, 21257 + # First try to convert the key to a location + # If that fails, raise a KeyError if an integer + # index, otherwise, see if key is an integer, and + # try that + try: + iloc = self.get_loc(key) + return s[iloc] + except KeyError: + if len(self) > 0 and (self.holds_integer() or self.is_boolean()): + raise + elif is_integer(key): + return s[key] - k = self._convert_scalar_indexer(k, kind="getitem") + k = self._convert_scalar_indexer(key, kind="getitem") try: return self._engine.get_value(s, k, tz=getattr(series.dtype, "tz", None)) except KeyError as e1: diff --git a/pandas/core/indexes/category.py b/pandas/core/indexes/category.py index a247a986fcb55..a066ed8277527 100644 --- a/pandas/core/indexes/category.py +++ b/pandas/core/indexes/category.py @@ -503,8 +503,8 @@ def get_value(self, series: AnyArrayLike, key: Any): Any The element of the series at the position indicated by the key """ + k = key try: - k = com.values_from_object(key) k = self._convert_scalar_indexer(k, kind="getitem") indexer = self.get_loc(k) return series.take([indexer])[0] diff --git a/pandas/core/indexes/numeric.py b/pandas/core/indexes/numeric.py index 53f96ace890fb..e7e13fd1ca742 100644 --- a/pandas/core/indexes/numeric.py +++ b/pandas/core/indexes/numeric.py @@ -1,3 +1,5 @@ +from typing import TYPE_CHECKING + import numpy as np from pandas._libs import index as libindex, lib @@ -38,6 +40,9 @@ ) from pandas.core.ops import get_op_result_name +if TYPE_CHECKING: + from pandas import Series + _num_index_shared_docs = dict() @@ -438,17 +443,18 @@ def _format_native_types( ) return formatter.get_result_as_array() - def get_value(self, series, key): + def get_value(self, series: "Series", key): """ We always want to get an index value, never a value. """ if not is_scalar(key): raise InvalidIndexError - k = com.values_from_object(key) - loc = self.get_loc(k) - new_values = com.values_from_object(series)[loc] + loc = self.get_loc(key) + if not is_scalar(loc): + return series.iloc[loc] + new_values = series._values[loc] return new_values def equals(self, other) -> bool: diff --git a/pandas/core/series.py b/pandas/core/series.py index 22b347c39fc54..ec9475c6dcba9 100644 --- a/pandas/core/series.py +++ b/pandas/core/series.py @@ -808,6 +808,10 @@ def _slice(self, slobj: slice, axis: int = 0, kind=None) -> "Series": def __getitem__(self, key): key = com.apply_if_callable(key, self) + + if key is Ellipsis: + return self + try: result = self.index.get_value(self, key) @@ -830,8 +834,6 @@ def __getitem__(self, key): if isinstance(key, tuple) and isinstance(self.index, MultiIndex): # kludge pass - elif key is Ellipsis: - return self elif com.is_bool_indexer(key): pass else: @@ -939,7 +941,7 @@ def _get_value(self, label, takeable: bool = False): """ if takeable: return com.maybe_box_datetimelike(self._values[label]) - return self.index.get_value(self._values, label) + return self.index.get_value(self, label) def __setitem__(self, key, value): key = com.apply_if_callable(key, self)