From 30e01469852c23e43b172a3a953177f8c6e830b6 Mon Sep 17 00:00:00 2001 From: Rob <124158982+rob-sil@users.noreply.github.com> Date: Sat, 10 Aug 2024 07:04:39 -0700 Subject: [PATCH 1/2] Handle nonexistent end dates for resampling --- doc/source/whatsnew/v3.0.0.rst | 1 + pandas/core/resample.py | 2 +- pandas/tests/resample/test_datetime_index.py | 14 ++++++++++++++ 3 files changed, 16 insertions(+), 1 deletion(-) diff --git a/doc/source/whatsnew/v3.0.0.rst b/doc/source/whatsnew/v3.0.0.rst index 3de65fe6f682c..035a22a7b5a56 100644 --- a/doc/source/whatsnew/v3.0.0.rst +++ b/doc/source/whatsnew/v3.0.0.rst @@ -615,6 +615,7 @@ Groupby/resample/rolling - Bug in :meth:`DataFrameGroupBy.cumsum` where it did not return the correct dtype when the label contained ``None``. (:issue:`58811`) - Bug in :meth:`DataFrameGroupby.transform` and :meth:`SeriesGroupby.transform` with a reducer and ``observed=False`` that coerces dtype to float when there are unobserved categories. (:issue:`55326`) - Bug in :meth:`Rolling.apply` where the applied function could be called on fewer than ``min_period`` periods if ``method="table"``. (:issue:`58868`) +- Bug in :meth:`Series.resample` could raise when the the date range ended shortly before DST. (:issue:`58380`) Reshaping ^^^^^^^^^ diff --git a/pandas/core/resample.py b/pandas/core/resample.py index 8ee71ea2293e6..b621fcf9a6415 100644 --- a/pandas/core/resample.py +++ b/pandas/core/resample.py @@ -2466,7 +2466,7 @@ def _get_timestamp_range_edges( ) if isinstance(freq, Day): first = first.tz_localize(index_tz) - last = last.tz_localize(index_tz) + last = last.tz_localize(index_tz, nonexistent="shift_forward") else: first = first.normalize() last = last.normalize() diff --git a/pandas/tests/resample/test_datetime_index.py b/pandas/tests/resample/test_datetime_index.py index dc2ddcc70828f..c81a9c23dfe29 100644 --- a/pandas/tests/resample/test_datetime_index.py +++ b/pandas/tests/resample/test_datetime_index.py @@ -958,6 +958,20 @@ def _create_series(values, timestamps, freq="D"): tm.assert_series_equal(result, expected) +def test_resample_dst_midnight_last_nonexistent(): + # GH 58380 + ts = Series( + 1, + date_range("2024-04-19", "2024-04-20", tz="Africa/Cairo", freq="15min"), + ) + + expected = Series([len(ts)], index=DatetimeIndex([ts.index[0]], freq="7D")) + + result = ts.resample("7D").sum() + print(f"{result=}") + tm.assert_series_equal(result, expected) + + def test_resample_daily_anchored(unit): rng = date_range("1/1/2000 0:00:00", periods=10000, freq="min").as_unit(unit) ts = Series(np.random.default_rng(2).standard_normal(len(rng)), index=rng) From ef9ffe91b9324ef3c1b1618c60b7981b02a0f8d1 Mon Sep 17 00:00:00 2001 From: Rob <124158982+rob-sil@users.noreply.github.com> Date: Sun, 11 Aug 2024 10:36:53 -0700 Subject: [PATCH 2/2] Fixes --- doc/source/whatsnew/v3.0.0.rst | 2 +- pandas/tests/resample/test_datetime_index.py | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/doc/source/whatsnew/v3.0.0.rst b/doc/source/whatsnew/v3.0.0.rst index 035a22a7b5a56..b0be926a478f6 100644 --- a/doc/source/whatsnew/v3.0.0.rst +++ b/doc/source/whatsnew/v3.0.0.rst @@ -615,7 +615,7 @@ Groupby/resample/rolling - Bug in :meth:`DataFrameGroupBy.cumsum` where it did not return the correct dtype when the label contained ``None``. (:issue:`58811`) - Bug in :meth:`DataFrameGroupby.transform` and :meth:`SeriesGroupby.transform` with a reducer and ``observed=False`` that coerces dtype to float when there are unobserved categories. (:issue:`55326`) - Bug in :meth:`Rolling.apply` where the applied function could be called on fewer than ``min_period`` periods if ``method="table"``. (:issue:`58868`) -- Bug in :meth:`Series.resample` could raise when the the date range ended shortly before DST. (:issue:`58380`) +- Bug in :meth:`Series.resample` could raise when the the date range ended shortly before a non-existent time. (:issue:`58380`) Reshaping ^^^^^^^^^ diff --git a/pandas/tests/resample/test_datetime_index.py b/pandas/tests/resample/test_datetime_index.py index c81a9c23dfe29..179f2c0e6cfa9 100644 --- a/pandas/tests/resample/test_datetime_index.py +++ b/pandas/tests/resample/test_datetime_index.py @@ -968,7 +968,6 @@ def test_resample_dst_midnight_last_nonexistent(): expected = Series([len(ts)], index=DatetimeIndex([ts.index[0]], freq="7D")) result = ts.resample("7D").sum() - print(f"{result=}") tm.assert_series_equal(result, expected)