Skip to content

Commit 3d4910e

Browse files
jorisvandenbosscheproost
authored andcommitted
BUG: Index.get_value implementation for ExtensionArray (pandas-dev#29926)
1 parent 751cb70 commit 3d4910e

File tree

2 files changed

+42
-16
lines changed

2 files changed

+42
-16
lines changed

pandas/core/indexes/base.py

+21-16
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,7 @@
6969
from pandas.core.arrays import ExtensionArray
7070
from pandas.core.base import IndexOpsMixin, PandasObject
7171
import pandas.core.common as com
72+
from pandas.core.construction import extract_array
7273
from pandas.core.indexers import maybe_convert_indices
7374
from pandas.core.indexes.frozen import FrozenList
7475
import pandas.core.missing as missing
@@ -4489,22 +4490,26 @@ def get_value(self, series, key):
44894490
# if we have something that is Index-like, then
44904491
# use this, e.g. DatetimeIndex
44914492
# Things like `Series._get_value` (via .at) pass the EA directly here.
4492-
s = getattr(series, "_values", series)
4493-
if isinstance(s, (ExtensionArray, Index)) and is_scalar(key):
4494-
# GH 20882, 21257
4495-
# Unify Index and ExtensionArray treatment
4496-
# First try to convert the key to a location
4497-
# If that fails, raise a KeyError if an integer
4498-
# index, otherwise, see if key is an integer, and
4499-
# try that
4500-
try:
4501-
iloc = self.get_loc(key)
4502-
return s[iloc]
4503-
except KeyError:
4504-
if len(self) > 0 and (self.holds_integer() or self.is_boolean()):
4505-
raise
4506-
elif is_integer(key):
4507-
return s[key]
4493+
s = extract_array(series, extract_numpy=True)
4494+
if isinstance(s, ExtensionArray):
4495+
if is_scalar(key):
4496+
# GH 20882, 21257
4497+
# First try to convert the key to a location
4498+
# If that fails, raise a KeyError if an integer
4499+
# index, otherwise, see if key is an integer, and
4500+
# try that
4501+
try:
4502+
iloc = self.get_loc(key)
4503+
return s[iloc]
4504+
except KeyError:
4505+
if len(self) > 0 and (self.holds_integer() or self.is_boolean()):
4506+
raise
4507+
elif is_integer(key):
4508+
return s[key]
4509+
else:
4510+
# if key is not a scalar, directly raise an error (the code below
4511+
# would convert to numpy arrays and raise later any way) - GH29926
4512+
raise InvalidIndexError(key)
45084513

45094514
s = com.values_from_object(series)
45104515
k = com.values_from_object(key)

pandas/tests/extension/decimal/test_decimal.py

+21
Original file line numberDiff line numberDiff line change
@@ -478,3 +478,24 @@ def DecimalArray__my_sum(self):
478478
s = pd.Series(DecimalArray(data))
479479
result = s.groupby(np.array([0, 0, 0, 1, 1])).agg(lambda x: x.values.my_sum())
480480
tm.assert_series_equal(result, expected, check_names=False)
481+
482+
483+
def test_indexing_no_materialize(monkeypatch):
484+
# See https://github.com/pandas-dev/pandas/issues/29708
485+
# Ensure that indexing operations do not materialize (convert to a numpy
486+
# array) the ExtensionArray unnecessary
487+
488+
def DecimalArray__array__(self, dtype=None):
489+
raise Exception("tried to convert a DecimalArray to a numpy array")
490+
491+
monkeypatch.setattr(DecimalArray, "__array__", DecimalArray__array__, raising=False)
492+
493+
data = make_data()
494+
s = pd.Series(DecimalArray(data))
495+
df = pd.DataFrame({"a": s, "b": range(len(s))})
496+
497+
# ensure the following operations do not raise an error
498+
s[s > 0.5]
499+
df[s > 0.5]
500+
s.at[0]
501+
df.at[0, "a"]

0 commit comments

Comments
 (0)