From 5fc5b04082201f40e9402625e222225c3f9736d8 Mon Sep 17 00:00:00 2001 From: "tobias.pitters" Date: Wed, 29 Jun 2022 11:01:19 +0200 Subject: [PATCH 1/9] fix regression --- pandas/core/indexes/datetimelike.py | 8 +++++++- pandas/tests/frame/indexing/test_getitem.py | 11 +++++++++++ 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/pandas/core/indexes/datetimelike.py b/pandas/core/indexes/datetimelike.py index 811dc72e9b908..9e763cd759ea6 100644 --- a/pandas/core/indexes/datetimelike.py +++ b/pandas/core/indexes/datetimelike.py @@ -222,7 +222,13 @@ def _parsed_string_to_bounds(self, reso: Resolution, parsed): def _parse_with_reso(self, label: str): # overridden by TimedeltaIndex - parsed, reso_str = parsing.parse_time_string(label, self.freq) + # todo: here we changed self.freq to these two lines + try: + if self.freq is None or hasattr(self.freq, 'rule_code'): + freq = self.freq + except NotImplementedError: + freq = getattr(self, "freqstr", getattr(self, "inferred_freq", None)) + parsed, reso_str = parsing.parse_time_string(label, freq) reso = Resolution.from_attrname(reso_str) return parsed, reso diff --git a/pandas/tests/frame/indexing/test_getitem.py b/pandas/tests/frame/indexing/test_getitem.py index 7994c56f8d68b..cfe73cabf578b 100644 --- a/pandas/tests/frame/indexing/test_getitem.py +++ b/pandas/tests/frame/indexing/test_getitem.py @@ -16,6 +16,8 @@ concat, get_dummies, period_range, + date_range, + DateOffset ) import pandas._testing as tm from pandas.core.arrays import SparseArray @@ -172,6 +174,14 @@ def test_getitem_iloc_two_dimensional_generator(self): expected = Series([5, 6], name="b", index=[1, 2]) tm.assert_series_equal(result, expected) + def test_getitem_iloc_dateoffset_days(self): + # GH 46671 + df = DataFrame(list(range(10)), index=date_range('01-01-2022', periods=10)) + df = df.asfreq(DateOffset(days=1)) + result = df.loc['2022-01-01': '2022-01-03'] + expected = DataFrame([0, 1, 2], index=DatetimeIndex(['2022-01-01', '2022-01-02', '2022-01-03'], + dtype='datetime64[ns]', freq=DateOffset(days=1))) + tm.assert_frame_equal(result, expected) class TestGetitemCallable: def test_getitem_callable(self, float_frame): @@ -426,3 +436,4 @@ def test_getitem_dict_and_set_deprecated(self, key): ) with tm.assert_produces_warning(FutureWarning): df[key] + From 92c499eb50cd01c70fc9e58e2e8e3ece05abe6a2 Mon Sep 17 00:00:00 2001 From: "tobias.pitters" Date: Wed, 29 Jun 2022 11:08:52 +0200 Subject: [PATCH 2/9] add whatsnew entry --- doc/source/whatsnew/v1.4.4.rst | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/doc/source/whatsnew/v1.4.4.rst b/doc/source/whatsnew/v1.4.4.rst index ef9537200bccd..7b74a217ccde7 100644 --- a/doc/source/whatsnew/v1.4.4.rst +++ b/doc/source/whatsnew/v1.4.4.rst @@ -14,8 +14,7 @@ including other versions of pandas. Fixed regressions ~~~~~~~~~~~~~~~~~ -- -- +- Fixed regression when slicing with :meth:`DataFrame.loc` with :class:`DateOffset`-index (:issue:`46900`) .. --------------------------------------------------------------------------- From e92c3e2f1667132c99e4bdbf8366e0d532c3c33e Mon Sep 17 00:00:00 2001 From: "tobias.pitters" Date: Wed, 29 Jun 2022 11:12:38 +0200 Subject: [PATCH 3/9] run pre-commit --- pandas/tests/frame/indexing/test_getitem.py | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/pandas/tests/frame/indexing/test_getitem.py b/pandas/tests/frame/indexing/test_getitem.py index cfe73cabf578b..8c31417c867ed 100644 --- a/pandas/tests/frame/indexing/test_getitem.py +++ b/pandas/tests/frame/indexing/test_getitem.py @@ -8,16 +8,16 @@ CategoricalDtype, CategoricalIndex, DataFrame, + DateOffset, DatetimeIndex, Index, MultiIndex, Series, Timestamp, concat, + date_range, get_dummies, period_range, - date_range, - DateOffset ) import pandas._testing as tm from pandas.core.arrays import SparseArray @@ -176,13 +176,20 @@ def test_getitem_iloc_two_dimensional_generator(self): def test_getitem_iloc_dateoffset_days(self): # GH 46671 - df = DataFrame(list(range(10)), index=date_range('01-01-2022', periods=10)) + df = DataFrame(list(range(10)), index=date_range("01-01-2022", periods=10)) df = df.asfreq(DateOffset(days=1)) - result = df.loc['2022-01-01': '2022-01-03'] - expected = DataFrame([0, 1, 2], index=DatetimeIndex(['2022-01-01', '2022-01-02', '2022-01-03'], - dtype='datetime64[ns]', freq=DateOffset(days=1))) + result = df.loc["2022-01-01":"2022-01-03"] + expected = DataFrame( + [0, 1, 2], + index=DatetimeIndex( + ["2022-01-01", "2022-01-02", "2022-01-03"], + dtype="datetime64[ns]", + freq=DateOffset(days=1), + ), + ) tm.assert_frame_equal(result, expected) + class TestGetitemCallable: def test_getitem_callable(self, float_frame): # GH#12533 @@ -436,4 +443,3 @@ def test_getitem_dict_and_set_deprecated(self, key): ) with tm.assert_produces_warning(FutureWarning): df[key] - From 7086415ffe712dbd4aef47db10af70e2dce28776 Mon Sep 17 00:00:00 2001 From: "tobias.pitters" Date: Wed, 29 Jun 2022 11:13:54 +0200 Subject: [PATCH 4/9] remove todo in code --- pandas/core/indexes/datetimelike.py | 1 - 1 file changed, 1 deletion(-) diff --git a/pandas/core/indexes/datetimelike.py b/pandas/core/indexes/datetimelike.py index 9e763cd759ea6..1cd2a99263c2a 100644 --- a/pandas/core/indexes/datetimelike.py +++ b/pandas/core/indexes/datetimelike.py @@ -222,7 +222,6 @@ def _parsed_string_to_bounds(self, reso: Resolution, parsed): def _parse_with_reso(self, label: str): # overridden by TimedeltaIndex - # todo: here we changed self.freq to these two lines try: if self.freq is None or hasattr(self.freq, 'rule_code'): freq = self.freq From 6572ad271913fddcaa81435b253ee3593451714e Mon Sep 17 00:00:00 2001 From: "tobias.pitters" Date: Wed, 29 Jun 2022 11:30:31 +0200 Subject: [PATCH 5/9] fix quotes --- pandas/core/indexes/datetimelike.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pandas/core/indexes/datetimelike.py b/pandas/core/indexes/datetimelike.py index 1cd2a99263c2a..2640c50a3009d 100644 --- a/pandas/core/indexes/datetimelike.py +++ b/pandas/core/indexes/datetimelike.py @@ -223,7 +223,7 @@ def _parsed_string_to_bounds(self, reso: Resolution, parsed): def _parse_with_reso(self, label: str): # overridden by TimedeltaIndex try: - if self.freq is None or hasattr(self.freq, 'rule_code'): + if self.freq is None or hasattr(self.freq, "rule_code"): freq = self.freq except NotImplementedError: freq = getattr(self, "freqstr", getattr(self, "inferred_freq", None)) From d9fa426e741b1a1a1490ef967266b6743ad2dec2 Mon Sep 17 00:00:00 2001 From: "tobias.pitters" Date: Mon, 11 Jul 2022 21:45:39 +0200 Subject: [PATCH 6/9] update tests --- pandas/tests/frame/indexing/test_getitem.py | 31 +++++++++++++++++++-- 1 file changed, 29 insertions(+), 2 deletions(-) diff --git a/pandas/tests/frame/indexing/test_getitem.py b/pandas/tests/frame/indexing/test_getitem.py index 8c31417c867ed..5f355f5303e45 100644 --- a/pandas/tests/frame/indexing/test_getitem.py +++ b/pandas/tests/frame/indexing/test_getitem.py @@ -176,8 +176,7 @@ def test_getitem_iloc_two_dimensional_generator(self): def test_getitem_iloc_dateoffset_days(self): # GH 46671 - df = DataFrame(list(range(10)), index=date_range("01-01-2022", periods=10)) - df = df.asfreq(DateOffset(days=1)) + df = DataFrame(list(range(10)), index=date_range("01-01-2022", periods=10, freq=DateOffset(days=1))) result = df.loc["2022-01-01":"2022-01-03"] expected = DataFrame( [0, 1, 2], @@ -189,6 +188,34 @@ def test_getitem_iloc_dateoffset_days(self): ) tm.assert_frame_equal(result, expected) + df = DataFrame(list(range(10)), index=date_range("01-01-2022", periods=10, freq=DateOffset(days=1, hours=2))) + result = df.loc["2022-01-01":"2022-01-03"] + expected = DataFrame( + [0, 1, 2], + index=DatetimeIndex( + ["2022-01-01 00:00:00", "2022-01-02 02:00:00", "2022-01-03 04:00:00"], + dtype="datetime64[ns]", + freq=DateOffset(days=1, hours=2), + ), + ) + tm.assert_frame_equal(result, expected) + + + df = DataFrame(list(range(10)), index=date_range("01-01-2022", periods=10, freq=DateOffset(minutes=3))) + result = df.loc["2022-01-01":"2022-01-03"] + expected = DataFrame( + [0, 1, 2, 3, 4, 5, 6, 7, 8, 9], + index=DatetimeIndex( + ["2022-01-01 00:00:00", "2022-01-01 00:03:00", "2022-01-01 00:06:00", + "2022-01-01 00:09:00", "2022-01-01 00:12:00", "2022-01-01 00:15:00", + "2022-01-01 00:18:00", "2022-01-01 00:21:00", "2022-01-01 00:24:00", + "2022-01-01 00:27:00"], + dtype="datetime64[ns]", + freq=DateOffset(minutes=3), + ), + ) + tm.assert_frame_equal(result, expected) + class TestGetitemCallable: def test_getitem_callable(self, float_frame): From fb11c6641500d5bc5a5689bafba755dfa280eb31 Mon Sep 17 00:00:00 2001 From: "tobias.pitters" Date: Mon, 11 Jul 2022 21:49:00 +0200 Subject: [PATCH 7/9] update test --- pandas/tests/frame/indexing/test_getitem.py | 34 ++++++++++++++++----- 1 file changed, 26 insertions(+), 8 deletions(-) diff --git a/pandas/tests/frame/indexing/test_getitem.py b/pandas/tests/frame/indexing/test_getitem.py index 5f355f5303e45..3a3cefc5a3d2a 100644 --- a/pandas/tests/frame/indexing/test_getitem.py +++ b/pandas/tests/frame/indexing/test_getitem.py @@ -176,7 +176,10 @@ def test_getitem_iloc_two_dimensional_generator(self): def test_getitem_iloc_dateoffset_days(self): # GH 46671 - df = DataFrame(list(range(10)), index=date_range("01-01-2022", periods=10, freq=DateOffset(days=1))) + df = DataFrame( + list(range(10)), + index=date_range("01-01-2022", periods=10, freq=DateOffset(days=1)), + ) result = df.loc["2022-01-01":"2022-01-03"] expected = DataFrame( [0, 1, 2], @@ -188,7 +191,12 @@ def test_getitem_iloc_dateoffset_days(self): ) tm.assert_frame_equal(result, expected) - df = DataFrame(list(range(10)), index=date_range("01-01-2022", periods=10, freq=DateOffset(days=1, hours=2))) + df = DataFrame( + list(range(10)), + index=date_range( + "01-01-2022", periods=10, freq=DateOffset(days=1, hours=2) + ), + ) result = df.loc["2022-01-01":"2022-01-03"] expected = DataFrame( [0, 1, 2], @@ -200,16 +208,26 @@ def test_getitem_iloc_dateoffset_days(self): ) tm.assert_frame_equal(result, expected) - - df = DataFrame(list(range(10)), index=date_range("01-01-2022", periods=10, freq=DateOffset(minutes=3))) + df = DataFrame( + list(range(10)), + index=date_range("01-01-2022", periods=10, freq=DateOffset(minutes=3)), + ) result = df.loc["2022-01-01":"2022-01-03"] expected = DataFrame( [0, 1, 2, 3, 4, 5, 6, 7, 8, 9], index=DatetimeIndex( - ["2022-01-01 00:00:00", "2022-01-01 00:03:00", "2022-01-01 00:06:00", - "2022-01-01 00:09:00", "2022-01-01 00:12:00", "2022-01-01 00:15:00", - "2022-01-01 00:18:00", "2022-01-01 00:21:00", "2022-01-01 00:24:00", - "2022-01-01 00:27:00"], + [ + "2022-01-01 00:00:00", + "2022-01-01 00:03:00", + "2022-01-01 00:06:00", + "2022-01-01 00:09:00", + "2022-01-01 00:12:00", + "2022-01-01 00:15:00", + "2022-01-01 00:18:00", + "2022-01-01 00:21:00", + "2022-01-01 00:24:00", + "2022-01-01 00:27:00", + ], dtype="datetime64[ns]", freq=DateOffset(minutes=3), ), From 54bd15891473a466bb23ab0202677536424454e9 Mon Sep 17 00:00:00 2001 From: "tobias.pitters" Date: Sun, 21 Aug 2022 12:55:37 +0200 Subject: [PATCH 8/9] update test_getitem --- pandas/tests/frame/indexing/test_getitem.py | 21 +-------------------- 1 file changed, 1 insertion(+), 20 deletions(-) diff --git a/pandas/tests/frame/indexing/test_getitem.py b/pandas/tests/frame/indexing/test_getitem.py index 3a3cefc5a3d2a..5f22c3eb8e9c8 100644 --- a/pandas/tests/frame/indexing/test_getitem.py +++ b/pandas/tests/frame/indexing/test_getitem.py @@ -213,26 +213,7 @@ def test_getitem_iloc_dateoffset_days(self): index=date_range("01-01-2022", periods=10, freq=DateOffset(minutes=3)), ) result = df.loc["2022-01-01":"2022-01-03"] - expected = DataFrame( - [0, 1, 2, 3, 4, 5, 6, 7, 8, 9], - index=DatetimeIndex( - [ - "2022-01-01 00:00:00", - "2022-01-01 00:03:00", - "2022-01-01 00:06:00", - "2022-01-01 00:09:00", - "2022-01-01 00:12:00", - "2022-01-01 00:15:00", - "2022-01-01 00:18:00", - "2022-01-01 00:21:00", - "2022-01-01 00:24:00", - "2022-01-01 00:27:00", - ], - dtype="datetime64[ns]", - freq=DateOffset(minutes=3), - ), - ) - tm.assert_frame_equal(result, expected) + tm.assert_frame_equal(result, df) class TestGetitemCallable: From d9c85e5e57c0ece160703e2cb2158acd59fb3887 Mon Sep 17 00:00:00 2001 From: Tobias Pitters <31857876+CloseChoice@users.noreply.github.com> Date: Mon, 22 Aug 2022 17:58:35 +0200 Subject: [PATCH 9/9] Update doc/source/whatsnew/v1.4.4.rst Co-authored-by: Simon Hawkins --- doc/source/whatsnew/v1.4.4.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/source/whatsnew/v1.4.4.rst b/doc/source/whatsnew/v1.4.4.rst index 6bc903a3a2ff7..e87d568d0cbf3 100644 --- a/doc/source/whatsnew/v1.4.4.rst +++ b/doc/source/whatsnew/v1.4.4.rst @@ -21,7 +21,7 @@ Fixed regressions - Fixed regression in :meth:`DataFrame.loc` not updating the cache correctly after values were set (:issue:`47867`) - Fixed regression in :meth:`DataFrame.loc` not aligning index in some cases when setting a :class:`DataFrame` (:issue:`47578`) - Fixed regression in :meth:`DataFrame.loc` setting a length-1 array like value to a single value in the DataFrame (:issue:`46268`) -- Fixed regression when slicing with :meth:`DataFrame.loc` with :class:`DateOffset`-index (:issue:`46900`) +- Fixed regression when slicing with :meth:`DataFrame.loc` with :class:`DateOffset`-index (:issue:`46671`) - Fixed regression in setting ``None`` or non-string value into a ``string``-dtype Series using a mask (:issue:`47628`) - Fixed regression in :meth:`DatetimeIndex.intersection` when the :class:`DatetimeIndex` has dates crossing daylight savings time (:issue:`46702`) - Fixed regression in :func:`merge` throwing an error when passing a :class:`Series` with a multi-level name (:issue:`47946`)