diff --git a/doc/source/whatsnew/v0.24.0.txt b/doc/source/whatsnew/v0.24.0.txt index 63fc7f43c0a63..c3cb9ac28ba4a 100644 --- a/doc/source/whatsnew/v0.24.0.txt +++ b/doc/source/whatsnew/v0.24.0.txt @@ -317,6 +317,7 @@ Reshaping ExtensionArray ^^^^^^^^^^^^^^ +- Bug in :meth:`Series.get` for ``Series`` using ``ExtensionArray`` and integer index (:issue:`21257`) - :meth:`Series.combine()` works correctly with :class:`~pandas.api.extensions.ExtensionArray` inside of :class:`Series` (:issue:`20825`) - :meth:`Series.combine()` with scalar argument now works for any function type (:issue:`21248`) - diff --git a/pandas/core/indexes/base.py b/pandas/core/indexes/base.py index 122f8662abb61..ba60d10099948 100644 --- a/pandas/core/indexes/base.py +++ b/pandas/core/indexes/base.py @@ -2988,16 +2988,20 @@ def get_value(self, series, key): # use this, e.g. DatetimeIndex s = getattr(series, '_values', None) if isinstance(s, (ExtensionArray, Index)) and is_scalar(key): - # GH 20825 + # GH 20882, 21257 # Unify Index and ExtensionArray treatment # First try to convert the key to a location - # If that fails, see if key is an integer, and + # 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 is_integer(key): + if (len(self) > 0 and + self.inferred_type in ['integer', 'boolean']): + raise + elif is_integer(key): return s[key] s = com._values_from_object(series) diff --git a/pandas/tests/extension/base/getitem.py b/pandas/tests/extension/base/getitem.py index 883b3f5588aef..e9df49780f119 100644 --- a/pandas/tests/extension/base/getitem.py +++ b/pandas/tests/extension/base/getitem.py @@ -130,7 +130,7 @@ def test_get(self, data): expected = s.iloc[[0, 1]] self.assert_series_equal(result, expected) - assert s.get(-1) == s.iloc[-1] + assert s.get(-1) is None assert s.get(s.index.max() + 1) is None s = pd.Series(data[:6], index=list('abcdef')) @@ -147,6 +147,11 @@ def test_get(self, data): assert s.get(-1) == s.iloc[-1] assert s.get(len(s)) is None + # GH 21257 + s = pd.Series(data) + s2 = s[::2] + assert s2.get(1) is None + def test_take_sequence(self, data): result = pd.Series(data)[[0, 1, 3]] assert result.iloc[0] == data[0] diff --git a/pandas/tests/series/indexing/test_indexing.py b/pandas/tests/series/indexing/test_indexing.py index 8571fbc10e9bb..25bc394e312a0 100644 --- a/pandas/tests/series/indexing/test_indexing.py +++ b/pandas/tests/series/indexing/test_indexing.py @@ -187,6 +187,49 @@ def test_getitem_box_float64(test_data): assert isinstance(value, np.float64) +@pytest.mark.parametrize( + 'arr', + [ + np.random.randn(10), + tm.makeDateIndex(10, name='a').tz_localize( + tz='US/Eastern'), + ]) +def test_get(arr): + # GH 21260 + s = Series(arr, index=[2 * i for i in range(len(arr))]) + assert s.get(4) == s.iloc[2] + + result = s.get([4, 6]) + expected = s.iloc[[2, 3]] + tm.assert_series_equal(result, expected) + + result = s.get(slice(2)) + expected = s.iloc[[0, 1]] + tm.assert_series_equal(result, expected) + + assert s.get(-1) is None + assert s.get(s.index.max() + 1) is None + + s = Series(arr[:6], index=list('abcdef')) + assert s.get('c') == s.iloc[2] + + result = s.get(slice('b', 'd')) + expected = s.iloc[[1, 2, 3]] + tm.assert_series_equal(result, expected) + + result = s.get('Z') + assert result is None + + assert s.get(4) == s.iloc[4] + assert s.get(-1) == s.iloc[-1] + assert s.get(len(s)) is None + + # GH 21257 + s = pd.Series(arr) + s2 = s[::2] + assert s2.get(1) is None + + def test_series_box_timestamp(): rng = pd.date_range('20090415', '20090519', freq='B') ser = Series(rng)