From 16e1a8b829a041b76deedea9e4ae9d0f3581c0ee Mon Sep 17 00:00:00 2001 From: Dr-Irv Date: Wed, 30 May 2018 13:33:41 -0400 Subject: [PATCH 1/4] BUG: Series.get() with ExtensionArray and integer index --- doc/source/whatsnew/v0.23.1.txt | 1 + pandas/core/indexes/base.py | 10 +++++++--- pandas/tests/extension/base/getitem.py | 7 ++++++- 3 files changed, 14 insertions(+), 4 deletions(-) diff --git a/doc/source/whatsnew/v0.23.1.txt b/doc/source/whatsnew/v0.23.1.txt index 35484e34ee9eb..b17c1d72b517c 100644 --- a/doc/source/whatsnew/v0.23.1.txt +++ b/doc/source/whatsnew/v0.23.1.txt @@ -81,6 +81,7 @@ Indexing - Bug in :meth:`Series.reset_index` where appropriate error was not raised with an invalid level name (:issue:`20925`) - Bug in :func:`interval_range` when ``start``/``periods`` or ``end``/``periods`` are specified with float ``start`` or ``end`` (:issue:`21161`) - Bug in :meth:`MultiIndex.set_names` where error raised for a ``MultiIndex`` with ``nlevels == 1`` (:issue:`21149`) +- Bug in :meth:`Series.get` for ``Series`` using ``ExtensionArray`` and integer index (:issue:`21257`) - I/O diff --git a/pandas/core/indexes/base.py b/pandas/core/indexes/base.py index 229624c7e6645..1d54017c2357c 100644 --- a/pandas/core/indexes/base.py +++ b/pandas/core/indexes/base.py @@ -2972,16 +2972,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] From f9401ab54b11acc1afe7d31e170705f6119e843b Mon Sep 17 00:00:00 2001 From: Dr-Irv Date: Thu, 31 May 2018 10:42:39 -0400 Subject: [PATCH 2/4] Add tests for get for different series types --- pandas/tests/test_base.py | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/pandas/tests/test_base.py b/pandas/tests/test_base.py index a5d83c1c26948..c9dc80840627c 100644 --- a/pandas/tests/test_base.py +++ b/pandas/tests/test_base.py @@ -998,6 +998,42 @@ def test_validate_bool_args(self): with pytest.raises(ValueError): self.int_series.drop_duplicates(inplace=value) + def test_get(self): + for o in self.objs: + if isinstance(o, Series): + s = o.set_axis([2 * i for i in range(len(o))], inplace=False) + 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(o.values[: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(o.values) + s2 = s[::2] + assert s2.get(1) is None + class TestTranspose(Ops): errmsg = "the 'axes' parameter is not supported" From 90661bbb758ae6ef0ac57b8bb39460ee72e56242 Mon Sep 17 00:00:00 2001 From: Dr-Irv Date: Tue, 19 Jun 2018 10:18:46 -0400 Subject: [PATCH 3/4] Move test to series/indexing/test_indexing and whatsnew 0.24.0 --- doc/source/whatsnew/v0.24.0.txt | 2 +- pandas/tests/series/indexing/test_indexing.py | 43 +++++++++++++++++++ pandas/tests/test_base.py | 36 ---------------- 3 files changed, 44 insertions(+), 37 deletions(-) diff --git a/doc/source/whatsnew/v0.24.0.txt b/doc/source/whatsnew/v0.24.0.txt index c23ed006ff637..d3686ac2f05ac 100644 --- a/doc/source/whatsnew/v0.24.0.txt +++ b/doc/source/whatsnew/v0.24.0.txt @@ -171,7 +171,7 @@ Strings Indexing ^^^^^^^^ -- +- Bug in :meth:`Series.get` for ``Series`` using ``ExtensionArray`` and integer index (:issue:`21257`) - - 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) diff --git a/pandas/tests/test_base.py b/pandas/tests/test_base.py index c9dc80840627c..a5d83c1c26948 100644 --- a/pandas/tests/test_base.py +++ b/pandas/tests/test_base.py @@ -998,42 +998,6 @@ def test_validate_bool_args(self): with pytest.raises(ValueError): self.int_series.drop_duplicates(inplace=value) - def test_get(self): - for o in self.objs: - if isinstance(o, Series): - s = o.set_axis([2 * i for i in range(len(o))], inplace=False) - 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(o.values[: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(o.values) - s2 = s[::2] - assert s2.get(1) is None - class TestTranspose(Ops): errmsg = "the 'axes' parameter is not supported" From 0854a0650f058b87527e0e77ad5f1c9ac32ea417 Mon Sep 17 00:00:00 2001 From: Jeff Reback Date: Thu, 28 Jun 2018 20:07:09 -0400 Subject: [PATCH 4/4] docs --- doc/source/whatsnew/v0.24.0.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/source/whatsnew/v0.24.0.txt b/doc/source/whatsnew/v0.24.0.txt index d502b1aebcbe6..76d08e84a6efd 100644 --- a/doc/source/whatsnew/v0.24.0.txt +++ b/doc/source/whatsnew/v0.24.0.txt @@ -209,7 +209,6 @@ Strings Interval ^^^^^^^^ -- Bug in :meth:`Series.get` for ``Series`` using ``ExtensionArray`` and integer index (:issue:`21257`) - Bug in the :class:`IntervalIndex` constructor where the ``closed`` parameter did not always override the inferred ``closed`` (:issue:`19370`) - - @@ -271,6 +270,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`) -