Skip to content

Commit ee80803

Browse files
authored
BUG: Correctly weekly resample over DST (#22941)
* test resample fix * move the localization until needed * BUG: Correctly weekly resample over DST * Move whatsnew to new section
1 parent fea27f0 commit ee80803

File tree

3 files changed

+33
-6
lines changed

3 files changed

+33
-6
lines changed

doc/source/whatsnew/v0.24.0.txt

+1
Original file line numberDiff line numberDiff line change
@@ -823,6 +823,7 @@ Groupby/Resample/Rolling
823823
- Bug in :meth:`Resampler.asfreq` when frequency of ``TimedeltaIndex`` is a subperiod of a new frequency (:issue:`13022`).
824824
- Bug in :meth:`SeriesGroupBy.mean` when values were integral but could not fit inside of int64, overflowing instead. (:issue:`22487`)
825825
- :func:`RollingGroupby.agg` and :func:`ExpandingGroupby.agg` now support multiple aggregation functions as parameters (:issue:`15072`)
826+
- Bug in :meth:`DataFrame.resample` and :meth:`Series.resample` when resampling by a weekly offset (``'W'``) across a DST transition (:issue:`9119`, :issue:`21459`)
826827

827828
Sparse
828829
^^^^^^

pandas/core/resample.py

+10-6
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,8 @@
1616
from pandas.tseries.frequencies import to_offset, is_subperiod, is_superperiod
1717
from pandas.core.indexes.datetimes import DatetimeIndex, date_range
1818
from pandas.core.indexes.timedeltas import TimedeltaIndex
19-
from pandas.tseries.offsets import DateOffset, Tick, Day, delta_to_nanoseconds
19+
from pandas.tseries.offsets import (DateOffset, Tick, Day,
20+
delta_to_nanoseconds, Nano)
2021
from pandas.core.indexes.period import PeriodIndex
2122
from pandas.errors import AbstractMethodError
2223
import pandas.core.algorithms as algos
@@ -1395,18 +1396,21 @@ def _get_time_bins(self, ax):
13951396
def _adjust_bin_edges(self, binner, ax_values):
13961397
# Some hacks for > daily data, see #1471, #1458, #1483
13971398

1398-
bin_edges = binner.asi8
1399-
14001399
if self.freq != 'D' and is_superperiod(self.freq, 'D'):
1401-
day_nanos = delta_to_nanoseconds(timedelta(1))
14021400
if self.closed == 'right':
1403-
bin_edges = bin_edges + day_nanos - 1
1401+
# GH 21459, GH 9119: Adjust the bins relative to the wall time
1402+
bin_edges = binner.tz_localize(None)
1403+
bin_edges = bin_edges + timedelta(1) - Nano(1)
1404+
bin_edges = bin_edges.tz_localize(binner.tz).asi8
1405+
else:
1406+
bin_edges = binner.asi8
14041407

14051408
# intraday values on last day
14061409
if bin_edges[-2] > ax_values.max():
14071410
bin_edges = bin_edges[:-1]
14081411
binner = binner[:-1]
1409-
1412+
else:
1413+
bin_edges = binner.asi8
14101414
return binner, bin_edges
14111415

14121416
def _get_time_delta_bins(self, ax):

pandas/tests/test_resample.py

+22
Original file line numberDiff line numberDiff line change
@@ -2114,6 +2114,28 @@ def test_downsample_across_dst(self):
21142114
freq='H'))
21152115
tm.assert_series_equal(result, expected)
21162116

2117+
def test_downsample_across_dst_weekly(self):
2118+
# GH 9119, GH 21459
2119+
df = DataFrame(index=DatetimeIndex([
2120+
'2017-03-25', '2017-03-26', '2017-03-27',
2121+
'2017-03-28', '2017-03-29'
2122+
], tz='Europe/Amsterdam'),
2123+
data=[11, 12, 13, 14, 15])
2124+
result = df.resample('1W').sum()
2125+
expected = DataFrame([23, 42], index=pd.DatetimeIndex([
2126+
'2017-03-26', '2017-04-02'
2127+
], tz='Europe/Amsterdam'))
2128+
tm.assert_frame_equal(result, expected)
2129+
2130+
idx = pd.date_range("2013-04-01", "2013-05-01", tz='Europe/London',
2131+
freq='H')
2132+
s = Series(index=idx)
2133+
result = s.resample('W').mean()
2134+
expected = Series(index=pd.date_range(
2135+
'2013-04-07', freq='W', periods=5, tz='Europe/London'
2136+
))
2137+
tm.assert_series_equal(result, expected)
2138+
21172139
def test_resample_with_nat(self):
21182140
# GH 13020
21192141
index = DatetimeIndex([pd.NaT,

0 commit comments

Comments
 (0)