diff --git a/doc/source/whatsnew/v3.0.0.rst b/doc/source/whatsnew/v3.0.0.rst index 1533f9267ce39..c03cd5ccf1fea 100644 --- a/doc/source/whatsnew/v3.0.0.rst +++ b/doc/source/whatsnew/v3.0.0.rst @@ -653,6 +653,7 @@ Groupby/resample/rolling - 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 a non-existent time. (:issue:`58380`) +- Bug in :meth:`Series.resample` where bin edges were not correct with closed="right" and label="right" for :class:`~pandas.tseries.offsets.BusinessDay` (:issue:`59495`) Reshaping ^^^^^^^^^ diff --git a/pandas/core/resample.py b/pandas/core/resample.py index b621fcf9a6415..77a5258b660cd 100644 --- a/pandas/core/resample.py +++ b/pandas/core/resample.py @@ -2173,7 +2173,11 @@ def _get_time_bins(self, ax: DatetimeIndex): if self.closed == "right": labels = binner if self.label == "right": - labels = labels[1:] + if binner.freqstr == "B": + labels = labels[1:-1] + bins = bins[0:-1] + else: + labels = labels[1:] elif self.label == "right": labels = labels[1:] diff --git a/pandas/tests/resample/test_datetime_index.py b/pandas/tests/resample/test_datetime_index.py index 179f2c0e6cfa9..7ff4a2e9f5db4 100644 --- a/pandas/tests/resample/test_datetime_index.py +++ b/pandas/tests/resample/test_datetime_index.py @@ -637,7 +637,7 @@ def test_resample_reresample(unit): s = Series(np.random.default_rng(2).random(len(dti)), dti) bs = s.resample("B", closed="right", label="right").mean() result = bs.resample("8h").mean() - assert len(result) == 25 + assert len(result) == 22 assert isinstance(result.index.freq, offsets.DateOffset) assert result.index.freq == offsets.Hour(8) @@ -2121,8 +2121,8 @@ def test_resample_c_b_closed_right(freq: str, unit): def test_resample_b_55282(unit): # https://github.com/pandas-dev/pandas/issues/55282 - dti = date_range("2023-09-26", periods=6, freq="12h", unit=unit) - ser = Series([1, 2, 3, 4, 5, 6], index=dti) + dti = date_range("2023-09-26", periods=5, freq="12h", unit=unit) + ser = Series([1, 2, 3, 4, 5], index=dti) result = ser.resample("B", closed="right", label="right").mean() exp_dti = DatetimeIndex( @@ -2130,12 +2130,11 @@ def test_resample_b_55282(unit): datetime(2023, 9, 26), datetime(2023, 9, 27), datetime(2023, 9, 28), - datetime(2023, 9, 29), ], freq="B", ).as_unit(unit) expected = Series( - [1.0, 2.5, 4.5, 6.0], + [1.0, 2.5, 4.5], index=exp_dti, ) tm.assert_series_equal(result, expected) @@ -2172,3 +2171,25 @@ def test_resample_A_raises(freq): s = Series(range(10), index=date_range("20130101", freq="D", periods=10)) with pytest.raises(ValueError, match=msg): s.resample(freq).mean() + + +def test_resample_b_59495(): + # GH#59495 + dti = date_range("8Aug2024", "13Aug2024", freq="D") + ser = Series(range(len(dti)), dti) + 1 + result = ser.resample("B", closed="right", label="right").sum() + + exp_dti = DatetimeIndex( + [ + datetime(2024, 8, 8), + datetime(2024, 8, 9), + datetime(2024, 8, 12), + datetime(2024, 8, 13), + ], + freq="B", + ).as_unit("ns") + expected = Series( + [1, 2, 12, 6], + index=exp_dti, + ) + tm.assert_series_equal(result, expected)