From 64f2197b86187af67aa550e89e656140e65119c6 Mon Sep 17 00:00:00 2001 From: jbrockmendel Date: Fri, 28 Jun 2019 16:58:29 -0500 Subject: [PATCH 1/4] Fix indexing on DatetimeBlock --- pandas/core/internals/blocks.py | 4 ++++ pandas/tests/groupby/aggregate/test_other.py | 5 +++-- pandas/tests/indexing/test_datetime.py | 9 +++++---- 3 files changed, 12 insertions(+), 6 deletions(-) diff --git a/pandas/core/internals/blocks.py b/pandas/core/internals/blocks.py index a131509a4ed10..5adafffe5c172 100644 --- a/pandas/core/internals/blocks.py +++ b/pandas/core/internals/blocks.py @@ -1539,6 +1539,10 @@ def iget(self, col): col, loc = col if not com.is_null_slice(col) and col != 0: raise IndexError("{0} only contains one item".format(self)) + if isinstance(col, slice): + if col != slice(None): + raise NotImplementedError(col) + return self.values[[loc]] return self.values[loc] else: if col != 0: diff --git a/pandas/tests/groupby/aggregate/test_other.py b/pandas/tests/groupby/aggregate/test_other.py index a061eaa1a2c6f..337646d80f300 100644 --- a/pandas/tests/groupby/aggregate/test_other.py +++ b/pandas/tests/groupby/aggregate/test_other.py @@ -421,11 +421,12 @@ def test_agg_timezone_round_trip(): assert ts == grouped.nth(0)['B'].iloc[0] assert ts == grouped.head(1)['B'].iloc[0] assert ts == grouped.first()['B'].iloc[0] - assert ts == grouped.apply(lambda x: x.iloc[0])[0] + assert ts == grouped.apply(lambda x: x.iloc[0]).iloc[0, 0] ts = df['B'].iloc[2] assert ts == grouped.last()['B'].iloc[0] - assert ts == grouped.apply(lambda x: x.iloc[-1])[0] + # FIXME: the next assertion is wrong; GH#26864 + assert ts == grouped.apply(lambda x: x.iloc[-1]).iloc[0, 0] def test_sum_uint64_overflow(): diff --git a/pandas/tests/indexing/test_datetime.py b/pandas/tests/indexing/test_datetime.py index d4da34cab6f5c..278fa6bd44f99 100644 --- a/pandas/tests/indexing/test_datetime.py +++ b/pandas/tests/indexing/test_datetime.py @@ -39,7 +39,7 @@ def test_setitem_with_datetime_tz(self): def test_indexing_with_datetime_tz(self): - # 8260 + # GH#8260 # support datetime64 with tz idx = Index(date_range('20130101', periods=3, tz='US/Eastern'), @@ -65,11 +65,12 @@ def test_indexing_with_datetime_tz(self): # indexing - fast_xs df = DataFrame({'a': date_range('2014-01-01', periods=10, tz='UTC')}) result = df.iloc[5] - expected = Timestamp('2014-01-06 00:00:00+0000', tz='UTC', freq='D') - assert result == expected + expected = Series([Timestamp('2014-01-06 00:00:00+0000', tz='UTC')], + index=['a'], name=5) + tm.assert_series_equal(result, expected) result = df.loc[5] - assert result == expected + tm.assert_series_equal(result, expected) # indexing - boolean result = df[df.a > df.a[3]] From ee96e17e7f94d4cbb414dd5d314333d825e276d4 Mon Sep 17 00:00:00 2001 From: jbrockmendel Date: Fri, 28 Jun 2019 17:03:39 -0500 Subject: [PATCH 2/4] whatsnew --- doc/source/whatsnew/v0.25.0.rst | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/doc/source/whatsnew/v0.25.0.rst b/doc/source/whatsnew/v0.25.0.rst index 1fe808e098860..f30ec9f44e4ce 100644 --- a/doc/source/whatsnew/v0.25.0.rst +++ b/doc/source/whatsnew/v0.25.0.rst @@ -743,7 +743,8 @@ Indexing - Bug in which :meth:`DataFrame.to_csv` caused a segfault for a reindexed data frame, when the indices were single-level :class:`MultiIndex` (:issue:`26303`). - Fixed bug where assigning a :class:`arrays.PandasArray` to a :class:`pandas.core.frame.DataFrame` would raise error (:issue:`26390`) - Allow keyword arguments for callable local reference used in the :meth:`DataFrame.query` string (:issue:`26426`) - +- Bug in :method:`DataFrame.loc` and :method:`DataFrame.iloc` on a :class:`DataFrame` with a single timezone-aware datetime64[ns] column incorrectly returning a scalar instead of a :class:`Series` (:issue:`27110`) +- Missing ^^^^^^^ From 6e9522ce79e1e4f7f6bc19afde43271abc40aac9 Mon Sep 17 00:00:00 2001 From: jbrockmendel Date: Sat, 29 Jun 2019 09:57:47 -0500 Subject: [PATCH 3/4] tests for each extension dtype --- pandas/core/internals/blocks.py | 2 +- pandas/tests/extension/base/getitem.py | 14 ++++++++++++++ pandas/tests/extension/test_numpy.py | 4 ++++ pandas/tests/groupby/aggregate/test_other.py | 5 ++++- 4 files changed, 23 insertions(+), 2 deletions(-) diff --git a/pandas/core/internals/blocks.py b/pandas/core/internals/blocks.py index 5adafffe5c172..94624e84b4514 100644 --- a/pandas/core/internals/blocks.py +++ b/pandas/core/internals/blocks.py @@ -1539,7 +1539,7 @@ def iget(self, col): col, loc = col if not com.is_null_slice(col) and col != 0: raise IndexError("{0} only contains one item".format(self)) - if isinstance(col, slice): + elif isinstance(col, slice): if col != slice(None): raise NotImplementedError(col) return self.values[[loc]] diff --git a/pandas/tests/extension/base/getitem.py b/pandas/tests/extension/base/getitem.py index dfc82c6041eae..6a5507b51b3ba 100644 --- a/pandas/tests/extension/base/getitem.py +++ b/pandas/tests/extension/base/getitem.py @@ -73,6 +73,20 @@ def test_loc_frame(self, data): result = df.loc[:3, 'A'] self.assert_series_equal(result, expected) + def test_loc_iloc_frame_single_dtype(self, data): + # GH#27110 bug in ExtensionBlock.iget caused df.iloc[n] to incorrectly + # return a scalar + df = pd.DataFrame({"A": data}) + expected = pd.Series([data[2]], index=["A"], name=2, dtype=data.dtype) + + result = df.loc[2] + self.assert_series_equal(result, expected) + + expected = pd.Series([data[-1]], index=["A"], name=len(data) - 1, + dtype=data.dtype) + result = df.iloc[-1] + self.assert_series_equal(result, expected) + def test_getitem_scalar(self, data): result = data[0] assert isinstance(result, data.dtype.type) diff --git a/pandas/tests/extension/test_numpy.py b/pandas/tests/extension/test_numpy.py index f31fa5b87cfe5..74ca296d23295 100644 --- a/pandas/tests/extension/test_numpy.py +++ b/pandas/tests/extension/test_numpy.py @@ -180,6 +180,10 @@ def test_take_series(self, data): # ValueError: PandasArray must be 1-dimensional. super().test_take_series(data) + @pytest.mark.xfail(reason="astype doesn't recognize data.dtype") + def test_loc_iloc_frame_single_dtype(self, data): + super().test_loc_iloc_frame_single_dtype(data) + class TestGroupby(BaseNumPyTests, base.BaseGroupbyTests): @skip_nested diff --git a/pandas/tests/groupby/aggregate/test_other.py b/pandas/tests/groupby/aggregate/test_other.py index 337646d80f300..903ffa23173cb 100644 --- a/pandas/tests/groupby/aggregate/test_other.py +++ b/pandas/tests/groupby/aggregate/test_other.py @@ -421,11 +421,14 @@ def test_agg_timezone_round_trip(): assert ts == grouped.nth(0)['B'].iloc[0] assert ts == grouped.head(1)['B'].iloc[0] assert ts == grouped.first()['B'].iloc[0] + + # GH#27110 applying iloc should return a DataFrame assert ts == grouped.apply(lambda x: x.iloc[0]).iloc[0, 0] ts = df['B'].iloc[2] assert ts == grouped.last()['B'].iloc[0] - # FIXME: the next assertion is wrong; GH#26864 + + # GH#27110 applying iloc should return a DataFrame assert ts == grouped.apply(lambda x: x.iloc[-1]).iloc[0, 0] From 2ec8eed6e768e404c38c0b73bbc9ac1357229146 Mon Sep 17 00:00:00 2001 From: jbrockmendel Date: Mon, 1 Jul 2019 13:43:15 -0700 Subject: [PATCH 4/4] whatsnew fixup --- doc/source/whatsnew/v0.25.0.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/source/whatsnew/v0.25.0.rst b/doc/source/whatsnew/v0.25.0.rst index f30ec9f44e4ce..d3f1e403e4bdf 100644 --- a/doc/source/whatsnew/v0.25.0.rst +++ b/doc/source/whatsnew/v0.25.0.rst @@ -743,7 +743,7 @@ Indexing - Bug in which :meth:`DataFrame.to_csv` caused a segfault for a reindexed data frame, when the indices were single-level :class:`MultiIndex` (:issue:`26303`). - Fixed bug where assigning a :class:`arrays.PandasArray` to a :class:`pandas.core.frame.DataFrame` would raise error (:issue:`26390`) - Allow keyword arguments for callable local reference used in the :meth:`DataFrame.query` string (:issue:`26426`) -- Bug in :method:`DataFrame.loc` and :method:`DataFrame.iloc` on a :class:`DataFrame` with a single timezone-aware datetime64[ns] column incorrectly returning a scalar instead of a :class:`Series` (:issue:`27110`) +- Bug in :meth:`DataFrame.loc` and :meth:`DataFrame.iloc` on a :class:`DataFrame` with a single timezone-aware datetime64[ns] column incorrectly returning a scalar instead of a :class:`Series` (:issue:`27110`) - Missing