From e73a9de51216ba99b6aaf6e110fc36a8c7bfe162 Mon Sep 17 00:00:00 2001 From: phofl Date: Mon, 6 Sep 2021 20:33:56 +0200 Subject: [PATCH 1/2] Regression in __getitem__ raising for slice DatetimeIndex --- doc/source/whatsnew/v1.3.3.rst | 1 + pandas/core/frame.py | 4 +--- pandas/tests/frame/indexing/test_getitem.py | 24 +++++++++++++++++++++ 3 files changed, 26 insertions(+), 3 deletions(-) diff --git a/doc/source/whatsnew/v1.3.3.rst b/doc/source/whatsnew/v1.3.3.rst index dd53fd187d38e..3e689f130cbe0 100644 --- a/doc/source/whatsnew/v1.3.3.rst +++ b/doc/source/whatsnew/v1.3.3.rst @@ -23,6 +23,7 @@ Fixed regressions - Fixed regression in :meth:`RangeIndex.where` and :meth:`RangeIndex.putmask` raising ``AssertionError`` when result did not represent a :class:`RangeIndex` (:issue:`43240`) - Fixed regression in :meth:`read_parquet` where the ``fastparquet`` engine would not work properly with fastparquet 0.7.0 (:issue:`43075`) - Fixed regression in :func:`is_list_like` where objects with ``__iter__`` set to ``None`` would be identified as iterable (:issue:`43373`) +- Fixed regression in :meth:`DataFrame.__getitem__` raising error for slice of :class:`DatetimeIndex` when index is non monotonic (:issue:`43223`) .. --------------------------------------------------------------------------- diff --git a/pandas/core/frame.py b/pandas/core/frame.py index 1d382e494cb48..c32d68d43269e 100644 --- a/pandas/core/frame.py +++ b/pandas/core/frame.py @@ -3459,9 +3459,7 @@ def __getitem__(self, key): indexer = convert_to_index_sliceable(self, key) if indexer is not None: if isinstance(indexer, np.ndarray): - indexer = lib.maybe_indices_to_slice( - indexer.astype(np.intp, copy=False), len(self) - ) + return self.take(indexer, axis=0) # either we have a slice or we have a string that can be converted # to a slice for partial-string date indexing return self._slice(indexer, axis=0) diff --git a/pandas/tests/frame/indexing/test_getitem.py b/pandas/tests/frame/indexing/test_getitem.py index 1b350b11b47e9..3028a433f2dae 100644 --- a/pandas/tests/frame/indexing/test_getitem.py +++ b/pandas/tests/frame/indexing/test_getitem.py @@ -8,6 +8,7 @@ CategoricalDtype, CategoricalIndex, DataFrame, + DatetimeIndex, Index, MultiIndex, Series, @@ -364,3 +365,26 @@ def test_getitem_slice_float64(self, frame_or_series): result = obj.loc[start:end] tm.assert_equal(result, expected) + + def test_getitem_datetime_slice(self): + # GH#43223 + df = DataFrame( + {"a": 0}, + index=DatetimeIndex( + [ + "11.01.2011 22:00", + "11.01.2011 23:00", + "12.01.2011 00:00", + "2011-01-13 00:00", + ] + ), + ) + with tm.assert_produces_warning(FutureWarning): + result = df["2011-01-01":"2011-11-01"] + expected = DataFrame( + {"a": 0}, + index=DatetimeIndex( + ["11.01.2011 22:00", "11.01.2011 23:00", "2011-01-13 00:00"] + ), + ) + tm.assert_frame_equal(result, expected) From 4ec175f2b919f5f83b80ef4f04caf754f86f053b Mon Sep 17 00:00:00 2001 From: phofl Date: Mon, 6 Sep 2021 21:45:16 +0200 Subject: [PATCH 2/2] Change to try casting --- pandas/core/frame.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/pandas/core/frame.py b/pandas/core/frame.py index 978359c8a205b..10e4cd9186c3d 100644 --- a/pandas/core/frame.py +++ b/pandas/core/frame.py @@ -3459,7 +3459,12 @@ def __getitem__(self, key): indexer = convert_to_index_sliceable(self, key) if indexer is not None: if isinstance(indexer, np.ndarray): - return self.take(indexer, axis=0) + indexer = lib.maybe_indices_to_slice( + indexer.astype(np.intp, copy=False), len(self) + ) + if isinstance(indexer, np.ndarray): + # GH#43223 If we can not convert, use take + return self.take(indexer, axis=0) # either we have a slice or we have a string that can be converted # to a slice for partial-string date indexing return self._slice(indexer, axis=0)