diff --git a/pandas/api/typing/__init__.py b/pandas/api/typing/__init__.py index de6657b58ee80..cd244dd416943 100644 --- a/pandas/api/typing/__init__.py +++ b/pandas/api/typing/__init__.py @@ -14,7 +14,6 @@ from pandas.core.indexes.frozen import FrozenList from pandas.core.resample import ( DatetimeIndexResamplerGroupby, - PeriodIndexResamplerGroupby, Resampler, TimedeltaIndexResamplerGroupby, TimeGrouper, @@ -48,7 +47,6 @@ "NAType", "NaTType", "NoDefault", - "PeriodIndexResamplerGroupby", "Resampler", "Rolling", "RollingGroupby", diff --git a/pandas/core/generic.py b/pandas/core/generic.py index 93a7de467dd97..40c154ed3217e 100644 --- a/pandas/core/generic.py +++ b/pandas/core/generic.py @@ -8835,12 +8835,6 @@ def resample( Which bin edge label to label bucket with. The default is 'left' for all frequency offsets except for 'ME', 'YE', 'QE', 'BME', 'BA', 'BQE', and 'W' which all have a default of 'right'. - convention : {{'start', 'end', 's', 'e'}}, default 'start' - For `PeriodIndex` only, controls whether to use the start or - end of `rule`. - - .. deprecated:: 2.2.0 - Convert PeriodIndex to DatetimeIndex before resampling instead. on : str, optional For a DataFrame, column to use instead of index for resampling. Column must be datetime-like. diff --git a/pandas/core/resample.py b/pandas/core/resample.py index 5ae88cff55d6d..3fdeab5bcf632 100644 --- a/pandas/core/resample.py +++ b/pandas/core/resample.py @@ -19,7 +19,6 @@ from pandas._libs import lib from pandas._libs.tslibs import ( BaseOffset, - IncompatibleFrequency, NaT, Period, Timedelta, @@ -79,10 +78,6 @@ ) from pandas.core.reshape.concat import concat -from pandas.tseries.frequencies import ( - is_subperiod, - is_superperiod, -) from pandas.tseries.offsets import ( Day, Tick, @@ -1938,128 +1933,6 @@ def _resampler_cls(self): return DatetimeIndexResampler -class PeriodIndexResampler(DatetimeIndexResampler): - # error: Incompatible types in assignment (expression has type "PeriodIndex", base - # class "DatetimeIndexResampler" defined the type as "DatetimeIndex") - ax: PeriodIndex # type: ignore[assignment] - - @property - def _resampler_for_grouping(self): - # TODO: Enforce in 3.0 (#55968) - warnings.warn( - "Resampling a groupby with a PeriodIndex is deprecated. " - "Cast to DatetimeIndex before resampling instead.", - FutureWarning, # pdlint: ignore[warning_class] - stacklevel=find_stack_level(), - ) - return PeriodIndexResamplerGroupby - - def _get_binner_for_time(self): - if isinstance(self.ax, DatetimeIndex): - return super()._get_binner_for_time() - return self._timegrouper._get_period_bins(self.ax) - - def _convert_obj(self, obj: NDFrameT) -> NDFrameT: - obj = super()._convert_obj(obj) - - if self._from_selection: - # see GH 14008, GH 12871 - msg = ( - "Resampling from level= or on= selection " - "with a PeriodIndex is not currently supported, " - "use .set_index(...) to explicitly set index" - ) - raise NotImplementedError(msg) - - # convert to timestamp - if isinstance(obj, DatetimeIndex): - obj = obj.to_timestamp(how=self.convention) - - return obj - - def _downsample(self, how, **kwargs): - """ - Downsample the cython defined function. - - Parameters - ---------- - how : string / cython mapped function - **kwargs : kw args passed to how function - """ - # we may need to actually resample as if we are timestamps - if isinstance(self.ax, DatetimeIndex): - return super()._downsample(how, **kwargs) - - ax = self.ax - - if is_subperiod(ax.freq, self.freq): - # Downsampling - return self._groupby_and_aggregate(how, **kwargs) - elif is_superperiod(ax.freq, self.freq): - if how == "ohlc": - # GH #13083 - # upsampling to subperiods is handled as an asfreq, which works - # for pure aggregating/reducing methods - # OHLC reduces along the time dimension, but creates multiple - # values for each period -> handle by _groupby_and_aggregate() - return self._groupby_and_aggregate(how) - return self.asfreq() - elif ax.freq == self.freq: - return self.asfreq() - - raise IncompatibleFrequency( - f"Frequency {ax.freq} cannot be resampled to {self.freq}, " - "as they are not sub or super periods" - ) - - def _upsample(self, method, limit: int | None = None, fill_value=None): - """ - Parameters - ---------- - method : {'backfill', 'bfill', 'pad', 'ffill'} - Method for upsampling. - limit : int, default None - Maximum size gap to fill when reindexing. - fill_value : scalar, default None - Value to use for missing values. - """ - # we may need to actually resample as if we are timestamps - if isinstance(self.ax, DatetimeIndex): - return super()._upsample(method, limit=limit, fill_value=fill_value) - - ax = self.ax - obj = self.obj - new_index = self.binner - - # Start vs. end of period - memb = ax.asfreq(self.freq, how=self.convention) - - # Get the fill indexer - if method == "asfreq": - method = None - indexer = memb.get_indexer(new_index, method=method, limit=limit) - new_obj = _take_new_index( - obj, - indexer, - new_index, - ) - return self._wrap_result(new_obj) - - -# error: Definition of "ax" in base class "_GroupByMixin" is incompatible with -# definition in base class "PeriodIndexResampler" -class PeriodIndexResamplerGroupby( # type: ignore[misc] - _GroupByMixin, PeriodIndexResampler -): - """ - Provides a resample of a groupby implementation. - """ - - @property - def _resampler_cls(self): - return PeriodIndexResampler - - class TimedeltaIndexResampler(DatetimeIndexResampler): # error: Incompatible types in assignment (expression has type "TimedeltaIndex", # base class "DatetimeIndexResampler" defined the type as "DatetimeIndex") @@ -2292,20 +2165,9 @@ def _get_resampler(self, obj: NDFrame) -> Resampler: gpr_index=ax, ) elif isinstance(ax, PeriodIndex): - if isinstance(ax, PeriodIndex): - # TODO: Enforce in 3.0 (#53481) - # GH#53481 - warnings.warn( - "Resampling with a PeriodIndex is deprecated. " - "Cast index to DatetimeIndex before resampling instead.", - FutureWarning, # pdlint: ignore[warning_class] - stacklevel=find_stack_level(), - ) - return PeriodIndexResampler( - obj, - timegrouper=self, - group_keys=self.group_keys, - gpr_index=ax, + raise TypeError( + "Resampling with a PeriodIndex is not supported. " + "Cast index to DatetimeIndex before resampling instead.", ) elif isinstance(ax, TimedeltaIndex): return TimedeltaIndexResampler( diff --git a/pandas/tests/api/test_api.py b/pandas/tests/api/test_api.py index 2c26f77102df1..8e90d0d66ca8d 100644 --- a/pandas/tests/api/test_api.py +++ b/pandas/tests/api/test_api.py @@ -267,7 +267,6 @@ class TestApi(Base): "NaTType", "NAType", "NoDefault", - "PeriodIndexResamplerGroupby", "Resampler", "Rolling", "RollingGroupby", diff --git a/pandas/tests/resample/test_base.py b/pandas/tests/resample/test_base.py index d9bd89af61aaf..605ef8dcff2ff 100644 --- a/pandas/tests/resample/test_base.py +++ b/pandas/tests/resample/test_base.py @@ -11,7 +11,6 @@ DatetimeIndex, Index, MultiIndex, - NaT, PeriodIndex, Series, TimedeltaIndex, @@ -104,13 +103,13 @@ def test_asfreq_fill_value(index): def test_resample_interpolate(index): # GH#12925 df = DataFrame(range(len(index)), index=index) - warn = None if isinstance(df.index, PeriodIndex): - warn = FutureWarning - msg = "Resampling with a PeriodIndex is deprecated" - with tm.assert_produces_warning(warn, match=msg): - result = df.resample("1min").asfreq().interpolate() - expected = df.resample("1min").interpolate() + msg = "Resampling with a PeriodIndex is not supported" + with pytest.raises(TypeError, match=msg): + df.resample("1min") + return + result = df.resample("1min").asfreq().interpolate() + expected = df.resample("1min").interpolate() tm.assert_frame_equal(result, expected) @@ -200,12 +199,12 @@ def test_resample_empty_series(freq, index, resample_method): # index is PeriodIndex, so convert to corresponding Period freq freq = "M" - warn = None if isinstance(ser.index, PeriodIndex): - warn = FutureWarning - msg = "Resampling with a PeriodIndex is deprecated" - with tm.assert_produces_warning(warn, match=msg): - rs = ser.resample(freq) + msg = "Resampling with a PeriodIndex is not supported" + with pytest.raises(TypeError, match=msg): + ser.resample(freq) + return + rs = ser.resample(freq) result = getattr(rs, resample_method)() if resample_method == "ohlc": @@ -248,40 +247,9 @@ def test_resample_empty_sum_string(string_dtype_no_object, min_count): tm.assert_series_equal(result, expected) -@pytest.mark.parametrize( - "freq", - [ - pytest.param("ME", marks=pytest.mark.xfail(reason="Don't know why this fails")), - "D", - "h", - ], -) -def test_resample_nat_index_series(freq, resample_method): - # GH39227 - - ser = Series(range(5), index=PeriodIndex([NaT] * 5, freq=freq)) - - msg = "Resampling with a PeriodIndex is deprecated" - with tm.assert_produces_warning(FutureWarning, match=msg): - rs = ser.resample(freq) - result = getattr(rs, resample_method)() - - if resample_method == "ohlc": - expected = DataFrame( - [], index=ser.index[:0], columns=["open", "high", "low", "close"] - ) - tm.assert_frame_equal(result, expected, check_dtype=False) - else: - expected = ser[:0].copy() - tm.assert_series_equal(result, expected, check_dtype=False) - tm.assert_index_equal(result.index, expected.index) - assert result.index.freq == expected.index.freq - - @pytest.mark.parametrize( "index", [ - PeriodIndex([], freq="D", name="a"), DatetimeIndex([], name="a"), TimedeltaIndex([], name="a"), ], @@ -303,19 +271,10 @@ def test_resample_count_empty_series(freq, index, resample_method): # index is PeriodIndex, so convert to corresponding Period freq freq = "M" - warn = None - if isinstance(ser.index, PeriodIndex): - warn = FutureWarning - msg = "Resampling with a PeriodIndex is deprecated" - with tm.assert_produces_warning(warn, match=msg): - rs = ser.resample(freq) - + rs = ser.resample(freq) result = getattr(rs, resample_method)() - index = _asfreq_compat(ser.index, freq) - expected = Series([], dtype="int64", index=index, name=ser.name) - tm.assert_series_equal(result, expected) @@ -339,12 +298,12 @@ def test_resample_empty_dataframe(index, freq, resample_method): # index is PeriodIndex, so convert to corresponding Period freq freq = "M" - warn = None if isinstance(df.index, PeriodIndex): - warn = FutureWarning - msg = "Resampling with a PeriodIndex is deprecated" - with tm.assert_produces_warning(warn, match=msg): - rs = df.resample(freq, group_keys=False) + msg = "Resampling with a PeriodIndex is not supported" + with pytest.raises(TypeError, match=msg): + df.resample(freq, group_keys=False) + return + rs = df.resample(freq, group_keys=False) result = getattr(rs, resample_method)() if resample_method == "ohlc": # TODO: no tests with len(df.columns) > 0 @@ -367,9 +326,7 @@ def test_resample_empty_dataframe(index, freq, resample_method): # test size for GH13212 (currently stays as df) -@pytest.mark.parametrize( - "index", [DatetimeIndex([]), TimedeltaIndex([]), PeriodIndex([], freq="D")] -) +@pytest.mark.parametrize("index", [DatetimeIndex([]), TimedeltaIndex([])]) @pytest.mark.parametrize("freq", ["ME", "D", "h"]) def test_resample_count_empty_dataframe(freq, index): # GH28427 @@ -402,9 +359,7 @@ def test_resample_count_empty_dataframe(freq, index): tm.assert_frame_equal(result, expected) -@pytest.mark.parametrize( - "index", [DatetimeIndex([]), TimedeltaIndex([]), PeriodIndex([], freq="D")] -) +@pytest.mark.parametrize("index", [DatetimeIndex([]), TimedeltaIndex([])]) @pytest.mark.parametrize("freq", ["ME", "D", "h"]) def test_resample_size_empty_dataframe(freq, index): # GH28427 @@ -423,18 +378,10 @@ def test_resample_size_empty_dataframe(freq, index): # index is PeriodIndex, so convert to corresponding Period freq freq = "M" - msg = "Resampling with a PeriodIndex" - warn = None - if isinstance(empty_frame_dti.index, PeriodIndex): - warn = FutureWarning - with tm.assert_produces_warning(warn, match=msg): - rs = empty_frame_dti.resample(freq) + rs = empty_frame_dti.resample(freq) result = rs.size() - index = _asfreq_compat(empty_frame_dti.index, freq) - expected = Series([], dtype="int64", index=index) - tm.assert_series_equal(result, expected) @@ -459,7 +406,6 @@ def test_resample_apply_empty_dataframe(index, freq, method): @pytest.mark.parametrize( "index", [ - PeriodIndex([], freq="M", name="a"), DatetimeIndex([], name="a"), TimedeltaIndex([], name="a"), ], @@ -470,16 +416,8 @@ def test_resample_empty_dtypes(index, dtype, resample_method): # Empty series were sometimes causing a segfault (for the functions # with Cython bounds-checking disabled) or an IndexError. We just run # them to ensure they no longer do. (GH #10228) - warn = None - if isinstance(index, PeriodIndex): - # GH#53511 - index = PeriodIndex([], freq="B", name=index.name) - warn = FutureWarning - msg = "Resampling with a PeriodIndex is deprecated" - empty_series_dti = Series([], index, dtype) - with tm.assert_produces_warning(warn, match=msg): - rs = empty_series_dti.resample("D", group_keys=False) + rs = empty_series_dti.resample("D", group_keys=False) try: getattr(rs, resample_method)() except DataError: @@ -491,7 +429,6 @@ def test_resample_empty_dtypes(index, dtype, resample_method): @pytest.mark.parametrize( "index", [ - PeriodIndex([], freq="D", name="a"), DatetimeIndex([], name="a"), TimedeltaIndex([], name="a"), ], @@ -513,18 +450,9 @@ def test_apply_to_empty_series(index, freq): # index is PeriodIndex, so convert to corresponding Period freq freq = "M" - msg = "Resampling with a PeriodIndex" - warn = None - if isinstance(ser.index, PeriodIndex): - warn = FutureWarning - - with tm.assert_produces_warning(warn, match=msg): - rs = ser.resample(freq, group_keys=False) - + rs = ser.resample(freq, group_keys=False) result = rs.apply(lambda x: 1) - with tm.assert_produces_warning(warn, match=msg): - expected = ser.resample(freq).apply("sum") - + expected = ser.resample(freq).apply("sum") tm.assert_series_equal(result, expected, check_dtype=False) @@ -533,7 +461,6 @@ def test_apply_to_empty_series(index, freq): [ timedelta_range("1 day", "10 day", freq="D"), date_range(datetime(2005, 1, 1), datetime(2005, 1, 10), freq="D"), - period_range(datetime(2005, 1, 1), datetime(2005, 1, 10), freq="D"), ], ) def test_resampler_is_iterable(index): @@ -541,16 +468,8 @@ def test_resampler_is_iterable(index): series = Series(range(len(index)), index=index) freq = "h" tg = Grouper(freq=freq, convention="start") - msg = "Resampling with a PeriodIndex" - warn = None - if isinstance(series.index, PeriodIndex): - warn = FutureWarning - - with tm.assert_produces_warning(warn, match=msg): - grouped = series.groupby(tg) - - with tm.assert_produces_warning(warn, match=msg): - resampled = series.resample(freq) + grouped = series.groupby(tg) + resampled = series.resample(freq) for (rk, rv), (gk, gv) in zip(resampled, grouped): assert rk == gk tm.assert_series_equal(rv, gv) @@ -561,7 +480,6 @@ def test_resampler_is_iterable(index): [ timedelta_range("1 day", "10 day", freq="D"), date_range(datetime(2005, 1, 1), datetime(2005, 1, 10), freq="D"), - period_range(datetime(2005, 1, 1), datetime(2005, 1, 10), freq="D"), ], ) def test_resample_quantile(index): @@ -569,14 +487,8 @@ def test_resample_quantile(index): ser = Series(range(len(index)), index=index) q = 0.75 freq = "h" - - msg = "Resampling with a PeriodIndex" - warn = None - if isinstance(ser.index, PeriodIndex): - warn = FutureWarning - with tm.assert_produces_warning(warn, match=msg): - result = ser.resample(freq).quantile(q) - expected = ser.resample(freq).agg(lambda x: x.quantile(q)).rename(ser.name) + result = ser.resample(freq).quantile(q) + expected = ser.resample(freq).agg(lambda x: x.quantile(q)).rename(ser.name) tm.assert_series_equal(result, expected) diff --git a/pandas/tests/resample/test_datetime_index.py b/pandas/tests/resample/test_datetime_index.py index 7b02b62bfd10c..4991f65392f0d 100644 --- a/pandas/tests/resample/test_datetime_index.py +++ b/pandas/tests/resample/test_datetime_index.py @@ -1005,22 +1005,6 @@ def test_resample_to_period_monthly_buglet(unit): tm.assert_index_equal(result.index, exp_index) -def test_period_with_agg(): - # aggregate a period resampler with a lambda - s2 = Series( - np.random.default_rng(2).integers(0, 5, 50), - index=period_range("2012-01-01", freq="h", periods=50), - dtype="float64", - ) - - expected = s2.to_timestamp().resample("D").mean().to_period() - msg = "Resampling with a PeriodIndex is deprecated" - with tm.assert_produces_warning(FutureWarning, match=msg): - rs = s2.resample("D") - result = rs.agg(lambda x: x.mean()) - tm.assert_series_equal(result, expected) - - def test_resample_segfault(unit): # GH 8573 # segfaulting in older versions diff --git a/pandas/tests/resample/test_period_index.py b/pandas/tests/resample/test_period_index.py index 2669e48e6a55d..c843328da1cd6 100644 --- a/pandas/tests/resample/test_period_index.py +++ b/pandas/tests/resample/test_period_index.py @@ -10,13 +10,6 @@ import numpy as np import pytest -from pandas._libs.tslibs.ccalendar import ( - DAYS, - MONTHS, -) -from pandas._libs.tslibs.period import IncompatibleFrequency -from pandas.errors import InvalidIndexError - import pandas as pd from pandas import ( DataFrame, @@ -34,10 +27,6 @@ from pandas.tseries import offsets -pytestmark = pytest.mark.filterwarnings( - "ignore:Resampling with a PeriodIndex is deprecated:FutureWarning" -) - @pytest.fixture def simple_period_range_series(): @@ -71,17 +60,6 @@ def test_asfreq(self, frame_or_series, freq): result = obj.to_timestamp().resample(freq).asfreq() tm.assert_almost_equal(result, expected) - start = obj.index[0].to_timestamp(how="start") - end = (obj.index[-1] + obj.index.freq).to_timestamp(how="start") - new_index = date_range(start=start, end=end, freq=freq, inclusive="left") - expected = obj.to_timestamp().reindex(new_index).to_period(freq) - - result = obj.resample(freq).asfreq() - tm.assert_almost_equal(result, expected) - - result = obj.resample(freq).asfreq().to_timestamp().to_period() - tm.assert_almost_equal(result, expected) - def test_asfreq_fill_value(self): # test for fill value during resampling, issue 3715 @@ -106,153 +84,6 @@ def test_asfreq_fill_value(self): result = frame.to_timestamp().resample("1h").asfreq(fill_value=3.0) tm.assert_frame_equal(result, expected) - @pytest.mark.parametrize("freq", ["h", "12h", "2D", "W"]) - @pytest.mark.parametrize("kwargs", [{"on": "date"}, {"level": "d"}]) - def test_selection(self, freq, kwargs): - # This is a bug, these should be implemented - # GH 14008 - index = period_range(datetime(2005, 1, 1), datetime(2005, 1, 10), freq="D") - rng = np.arange(len(index), dtype=np.int64) - df = DataFrame( - {"date": index, "a": rng}, - index=pd.MultiIndex.from_arrays([rng, index], names=["v", "d"]), - ) - msg = ( - "Resampling from level= or on= selection with a PeriodIndex is " - r"not currently supported, use \.set_index\(\.\.\.\) to " - "explicitly set index" - ) - with pytest.raises(NotImplementedError, match=msg): - df.resample(freq, **kwargs) - - @pytest.mark.parametrize("month", MONTHS) - @pytest.mark.parametrize("meth", ["ffill", "bfill"]) - @pytest.mark.parametrize("conv", ["start", "end"]) - @pytest.mark.parametrize( - ("offset", "period"), [("D", "D"), ("B", "B"), ("ME", "M"), ("QE", "Q")] - ) - def test_annual_upsample_cases( - self, offset, period, conv, meth, month, simple_period_range_series - ): - ts = simple_period_range_series("1/1/1990", "12/31/1991", freq=f"Y-{month}") - warn = FutureWarning if period == "B" else None - msg = r"PeriodDtype\[B\] is deprecated" - if warn is None: - msg = "Resampling with a PeriodIndex is deprecated" - warn = FutureWarning - with tm.assert_produces_warning(warn, match=msg): - result = getattr(ts.resample(period, convention=conv), meth)() - expected = result.to_timestamp(period, how=conv) - expected = expected.asfreq(offset, meth).to_period() - tm.assert_series_equal(result, expected) - - def test_basic_downsample(self, simple_period_range_series): - ts = simple_period_range_series("1/1/1990", "6/30/1995", freq="M") - result = ts.resample("Y-DEC").mean() - - expected = ts.groupby(ts.index.year).mean() - expected.index = period_range("1/1/1990", "6/30/1995", freq="Y-DEC") - tm.assert_series_equal(result, expected) - - # this is ok - tm.assert_series_equal(ts.resample("Y-DEC").mean(), result) - tm.assert_series_equal(ts.resample("Y").mean(), result) - - @pytest.mark.parametrize( - "rule,expected_error_msg", - [ - ("Y-DEC", ""), - ("Q-MAR", ""), - ("M", ""), - ("W-THU", ""), - ], - ) - def test_not_subperiod(self, simple_period_range_series, rule, expected_error_msg): - # These are incompatible period rules for resampling - ts = simple_period_range_series("1/1/1990", "6/30/1995", freq="W-WED") - msg = ( - "Frequency cannot be resampled to " - f"{expected_error_msg}, as they are not sub or super periods" - ) - with pytest.raises(IncompatibleFrequency, match=msg): - ts.resample(rule).mean() - - @pytest.mark.parametrize("freq", ["D", "2D"]) - def test_basic_upsample(self, freq, simple_period_range_series): - ts = simple_period_range_series("1/1/1990", "6/30/1995", freq="M") - result = ts.resample("Y-DEC").mean() - - msg = "The 'convention' keyword in Series.resample is deprecated" - with tm.assert_produces_warning(FutureWarning, match=msg): - resampled = result.resample(freq, convention="end").ffill() - expected = result.to_timestamp(freq, how="end") - expected = expected.asfreq(freq, "ffill").to_period(freq) - tm.assert_series_equal(resampled, expected) - - def test_upsample_with_limit(self): - rng = period_range("1/1/2000", periods=5, freq="Y") - ts = Series(np.random.default_rng(2).standard_normal(len(rng)), rng) - - msg = "The 'convention' keyword in Series.resample is deprecated" - with tm.assert_produces_warning(FutureWarning, match=msg): - result = ts.resample("M", convention="end").ffill(limit=2) - expected = ts.asfreq("M").reindex(result.index, method="ffill", limit=2) - tm.assert_series_equal(result, expected) - - def test_annual_upsample(self, simple_period_range_series): - ts = simple_period_range_series("1/1/1990", "12/31/1995", freq="Y-DEC") - df = DataFrame({"a": ts}) - rdf = df.resample("D").ffill() - exp = df["a"].resample("D").ffill() - tm.assert_series_equal(rdf["a"], exp) - - def test_annual_upsample2(self): - rng = period_range("2000", "2003", freq="Y-DEC") - ts = Series([1, 2, 3, 4], index=rng) - - result = ts.resample("M").ffill() - ex_index = period_range("2000-01", "2003-12", freq="M") - - expected = ts.asfreq("M", how="start").reindex(ex_index, method="ffill") - tm.assert_series_equal(result, expected) - - @pytest.mark.parametrize("month", MONTHS) - @pytest.mark.parametrize("convention", ["start", "end"]) - @pytest.mark.parametrize( - ("offset", "period"), [("D", "D"), ("B", "B"), ("ME", "M")] - ) - def test_quarterly_upsample( - self, month, offset, period, convention, simple_period_range_series - ): - freq = f"Q-{month}" - ts = simple_period_range_series("1/1/1990", "12/31/1995", freq=freq) - warn = FutureWarning if period == "B" else None - msg = r"PeriodDtype\[B\] is deprecated" - if warn is None: - msg = "Resampling with a PeriodIndex is deprecated" - warn = FutureWarning - with tm.assert_produces_warning(warn, match=msg): - result = ts.resample(period, convention=convention).ffill() - expected = result.to_timestamp(period, how=convention) - expected = expected.asfreq(offset, "ffill").to_period() - tm.assert_series_equal(result, expected) - - @pytest.mark.parametrize("target", ["D", "B"]) - @pytest.mark.parametrize("convention", ["start", "end"]) - def test_monthly_upsample(self, target, convention, simple_period_range_series): - ts = simple_period_range_series("1/1/1990", "12/31/1995", freq="M") - - warn = None if target == "D" else FutureWarning - msg = r"PeriodDtype\[B\] is deprecated" - if warn is None: - msg = "Resampling with a PeriodIndex is deprecated" - warn = FutureWarning - with tm.assert_produces_warning(warn, match=msg): - result = ts.resample(target, convention=convention).ffill() - expected = result.to_timestamp(target, how=convention) - expected = expected.asfreq(target, "ffill").to_period() - tm.assert_series_equal(result, expected) - def test_resample_basic(self): # GH3609 s = Series( @@ -266,43 +97,8 @@ def test_resample_basic(self): name="idx", ) expected = Series([34.5, 79.5], index=index) - result = s.to_period().resample("min").mean() + result = s.resample("min").mean().to_period() tm.assert_series_equal(result, expected) - result2 = s.resample("min").mean().to_period() - tm.assert_series_equal(result2, expected) - - @pytest.mark.parametrize( - "freq,expected_vals", [("M", [31, 29, 31, 9]), ("2M", [31 + 29, 31 + 9])] - ) - def test_resample_count(self, freq, expected_vals): - # GH12774 - series = Series(1, index=period_range(start="2000", periods=100)) - result = series.resample(freq).count() - expected_index = period_range( - start="2000", freq=freq, periods=len(expected_vals) - ) - expected = Series(expected_vals, index=expected_index) - tm.assert_series_equal(result, expected) - - def test_resample_same_freq(self, resample_method): - # GH12770 - series = Series(range(3), index=period_range(start="2000", periods=3, freq="M")) - expected = series - - result = getattr(series.resample("M"), resample_method)() - tm.assert_series_equal(result, expected) - - def test_resample_incompat_freq(self): - msg = ( - "Frequency cannot be resampled to , " - "as they are not sub or super periods" - ) - pi = period_range(start="2000", periods=3, freq="M") - ser = Series(range(3), index=pi) - rs = ser.resample("W") - with pytest.raises(IncompatibleFrequency, match=msg): - # TODO: should this raise at the resample call instead of at the mean call? - rs.mean() @pytest.mark.parametrize( "tz", @@ -408,109 +204,6 @@ def test_fill_method_and_how_upsample(self): both = s.resample("ME").ffill().resample("ME").last().astype("int64") tm.assert_series_equal(last, both) - @pytest.mark.parametrize("day", DAYS) - @pytest.mark.parametrize("target", ["D", "B"]) - @pytest.mark.parametrize("convention", ["start", "end"]) - def test_weekly_upsample(self, day, target, convention, simple_period_range_series): - freq = f"W-{day}" - ts = simple_period_range_series("1/1/1990", "12/31/1995", freq=freq) - - warn = None if target == "D" else FutureWarning - msg = r"PeriodDtype\[B\] is deprecated" - if warn is None: - msg = "Resampling with a PeriodIndex is deprecated" - warn = FutureWarning - with tm.assert_produces_warning(warn, match=msg): - result = ts.resample(target, convention=convention).ffill() - expected = result.to_timestamp(target, how=convention) - expected = expected.asfreq(target, "ffill").to_period() - tm.assert_series_equal(result, expected) - - def test_resample_to_timestamps(self, simple_period_range_series): - ts = simple_period_range_series("1/1/1990", "12/31/1995", freq="M") - - result = ts.resample("Y-DEC").mean().to_timestamp() - expected = ts.resample("Y-DEC").mean().to_timestamp(how="start") - tm.assert_series_equal(result, expected) - - @pytest.mark.parametrize("month", MONTHS) - def test_resample_to_quarterly(self, simple_period_range_series, month): - ts = simple_period_range_series("1990", "1992", freq=f"Y-{month}") - quar_ts = ts.resample(f"Q-{month}").ffill() - - stamps = ts.to_timestamp("D", how="start") - qdates = period_range( - ts.index[0].asfreq("D", "start"), - ts.index[-1].asfreq("D", "end"), - freq=f"Q-{month}", - ) - - expected = stamps.reindex(qdates.to_timestamp("D", "s"), method="ffill") - expected.index = qdates - - tm.assert_series_equal(quar_ts, expected) - - @pytest.mark.parametrize("how", ["start", "end"]) - def test_resample_to_quarterly_start_end(self, simple_period_range_series, how): - # conforms, but different month - ts = simple_period_range_series("1990", "1992", freq="Y-JUN") - msg = "The 'convention' keyword in Series.resample is deprecated" - with tm.assert_produces_warning(FutureWarning, match=msg): - result = ts.resample("Q-MAR", convention=how).ffill() - expected = ts.asfreq("Q-MAR", how=how) - expected = expected.reindex(result.index, method="ffill") - - # FIXME: don't leave commented-out - # .to_timestamp('D') - # expected = expected.resample('Q-MAR').ffill() - - tm.assert_series_equal(result, expected) - - def test_resample_fill_missing(self): - rng = PeriodIndex([2000, 2005, 2007, 2009], freq="Y") - - s = Series(np.random.default_rng(2).standard_normal(4), index=rng) - - stamps = s.to_timestamp() - filled = s.resample("Y").ffill() - expected = stamps.resample("YE").ffill().to_period("Y") - tm.assert_series_equal(filled, expected) - - def test_cant_fill_missing_dups(self): - rng = PeriodIndex([2000, 2005, 2005, 2007, 2007], freq="Y") - s = Series(np.random.default_rng(2).standard_normal(5), index=rng) - msg = "Reindexing only valid with uniquely valued Index objects" - with pytest.raises(InvalidIndexError, match=msg): - s.resample("Y").ffill() - - def test_resample_5minute(self): - rng = period_range("1/1/2000", "1/5/2000", freq="min") - ts = Series(np.random.default_rng(2).standard_normal(len(rng)), index=rng) - expected = ts.to_timestamp().resample("5min").mean() - result = ts.resample("5min").mean().to_timestamp() - tm.assert_series_equal(result, expected) - - expected = expected.to_period("5min") - result = ts.resample("5min").mean() - tm.assert_series_equal(result, expected) - result = ts.resample("5min").mean().to_timestamp().to_period() - tm.assert_series_equal(result, expected) - - def test_upsample_daily_business_daily(self, simple_period_range_series): - ts = simple_period_range_series("1/1/2000", "2/1/2000", freq="B") - - result = ts.resample("D").asfreq() - expected = ts.asfreq("D").reindex(period_range("1/3/2000", "2/1/2000")) - tm.assert_series_equal(result, expected) - - ts = simple_period_range_series("1/1/2000", "2/1/2000") - msg = "The 'convention' keyword in Series.resample is deprecated" - with tm.assert_produces_warning(FutureWarning, match=msg): - result = ts.resample("h", convention="s").asfreq() - exp_rng = period_range("1/1/2000", "2/1/2000 23:00", freq="h") - expected = ts.asfreq("h", how="s").reindex(exp_rng) - tm.assert_series_equal(result, expected) - def test_resample_irregular_sparse(self): dr = date_range(start="1/1/2012", freq="5min", periods=1000) s = Series(np.array(100), index=dr) @@ -560,10 +253,9 @@ def test_resample_tz_localized2(self): ) s = Series([1, 2], index=idx) - # GH#61985 changed this to behave like "B" rather than "24h" result = s.resample("D", closed="right", label="right").mean() - ex_index = date_range("2001-09-20", periods=2, freq="D", tz="Australia/Sydney") - expected = Series([np.nan, 1.5], index=ex_index) + ex_index = date_range("2001-09-21", periods=1, freq="D", tz="Australia/Sydney") + expected = Series([1.5], index=ex_index) tm.assert_series_equal(result, expected) @@ -617,14 +309,6 @@ def test_closed_left_corner(self): tm.assert_index_equal(result.index, ex_index) tm.assert_series_equal(result, exp) - def test_quarterly_resampling(self): - rng = period_range("2000Q1", periods=10, freq="Q-DEC") - ts = Series(np.arange(10), index=rng) - - result = ts.resample("Y").mean() - exp = ts.to_timestamp().resample("YE").mean().to_period() - tm.assert_series_equal(result, exp) - def test_resample_weekly_bug_1726(self): # 8/6/12 is a Monday ind = date_range(start="8/6/2012", end="8/26/2012", freq="D") @@ -721,14 +405,6 @@ def test_default_left_closed_label(self, from_freq, to_freq): resampled, df.resample(to_freq, closed="left", label="left").mean() ) - def test_all_values_single_bin(self): - # GH#2070 - index = period_range(start="2012-01-01", end="2012-12-31", freq="M") - ser = Series(np.random.default_rng(2).standard_normal(len(index)), index=index) - - result = ser.resample("Y").mean() - tm.assert_almost_equal(result.iloc[0], ser.mean()) - def test_evenly_divisible_with_no_extra_bins(self): # GH#4076 # when the frequency is evenly divisible, sometimes extra bins @@ -803,132 +479,6 @@ def test_evenly_divisible_with_no_extra_bins2(self): result = df.resample("7D").sum() tm.assert_frame_equal(result, expected) - @pytest.mark.parametrize("freq, period_mult", [("h", 24), ("12h", 2)]) - def test_upsampling_ohlc(self, freq, period_mult): - # GH 13083 - pi = period_range(start="2000", freq="D", periods=10) - s = Series(range(len(pi)), index=pi) - expected = s.to_timestamp().resample(freq).ohlc().to_period(freq) - - # timestamp-based resampling doesn't include all sub-periods - # of the last original period, so extend accordingly: - new_index = period_range(start="2000", freq=freq, periods=period_mult * len(pi)) - expected = expected.reindex(new_index) - result = s.resample(freq).ohlc() - tm.assert_frame_equal(result, expected) - - result = s.resample(freq).ohlc().to_timestamp().to_period() - tm.assert_frame_equal(result, expected) - - @pytest.mark.parametrize( - "periods, values", - [ - ( - [ - pd.NaT, - "1970-01-01 00:00:00", - pd.NaT, - "1970-01-01 00:00:02", - "1970-01-01 00:00:03", - ], - [2, 3, 5, 7, 11], - ), - ( - [ - pd.NaT, - pd.NaT, - "1970-01-01 00:00:00", - pd.NaT, - pd.NaT, - pd.NaT, - "1970-01-01 00:00:02", - "1970-01-01 00:00:03", - pd.NaT, - pd.NaT, - ], - [1, 2, 3, 5, 6, 8, 7, 11, 12, 13], - ), - ], - ) - @pytest.mark.parametrize( - "freq, expected_values", - [ - ("1s", [3, np.nan, 7, 11]), - ("2s", [3, (7 + 11) / 2]), - ("3s", [(3 + 7) / 2, 11]), - ], - ) - def test_resample_with_nat(self, periods, values, freq, expected_values): - # GH 13224 - index = PeriodIndex(periods, freq="s") - frame = DataFrame(values, index=index) - - expected_index = period_range( - "1970-01-01 00:00:00", periods=len(expected_values), freq=freq - ) - expected = DataFrame(expected_values, index=expected_index) - msg = "Resampling with a PeriodIndex is deprecated" - with tm.assert_produces_warning(FutureWarning, match=msg): - rs = frame.resample(freq) - result = rs.mean() - tm.assert_frame_equal(result, expected) - - def test_resample_with_only_nat(self): - # GH 13224 - pi = PeriodIndex([pd.NaT] * 3, freq="s") - frame = DataFrame([2, 3, 5], index=pi, columns=["a"]) - expected_index = PeriodIndex(data=[], freq=pi.freq) - expected = DataFrame(index=expected_index, columns=["a"], dtype="float64") - result = frame.resample("1s").mean() - tm.assert_frame_equal(result, expected) - - @pytest.mark.parametrize( - "start,end,start_freq,end_freq,offset", - [ - ("19910905", "19910909 03:00", "h", "24h", "10h"), - ("19910905", "19910909 12:00", "h", "24h", "10h"), - ("19910905", "19910909 23:00", "h", "24h", "10h"), - ("19910905 10:00", "19910909", "h", "24h", "10h"), - ("19910905 10:00", "19910909 10:00", "h", "24h", "10h"), - ("19910905", "19910909 10:00", "h", "24h", "10h"), - ("19910905 12:00", "19910909", "h", "24h", "10h"), - ("19910905 12:00", "19910909 03:00", "h", "24h", "10h"), - ("19910905 12:00", "19910909 12:00", "h", "24h", "10h"), - ("19910905 12:00", "19910909 12:00", "h", "24h", "34h"), - ("19910905 12:00", "19910909 12:00", "h", "17h", "10h"), - ("19910905 12:00", "19910909 12:00", "h", "17h", "3h"), - ("19910905", "19910913 06:00", "2h", "24h", "10h"), - ("19910905", "19910905 01:39", "Min", "5Min", "3Min"), - ("19910905", "19910905 03:18", "2Min", "5Min", "3Min"), - ], - ) - def test_resample_with_offset(self, start, end, start_freq, end_freq, offset): - # GH 23882 & 31809 - pi = period_range(start, end, freq=start_freq) - ser = Series(np.arange(len(pi)), index=pi) - msg = "Resampling with a PeriodIndex is deprecated" - with tm.assert_produces_warning(FutureWarning, match=msg): - rs = ser.resample(end_freq, offset=offset) - result = rs.mean() - result = result.to_timestamp(end_freq) - - expected = ser.to_timestamp().resample(end_freq, offset=offset).mean() - tm.assert_series_equal(result, expected) - - def test_resample_with_offset_month(self): - # GH 23882 & 31809 - pi = period_range("19910905 12:00", "19910909 1:00", freq="h") - ser = Series(np.arange(len(pi)), index=pi) - msg = "Resampling with a PeriodIndex is deprecated" - with tm.assert_produces_warning(FutureWarning, match=msg): - rs = ser.resample("M") - result = rs.mean() - result = result.to_timestamp("M") - expected = ser.to_timestamp().resample("ME").mean() - # TODO: is non-tick the relevant characteristic? (GH 33815) - expected.index = expected.index._with_freq(None) - tm.assert_series_equal(result, expected) - @pytest.mark.parametrize( "first,last,freq,freq_to_offset,exp_first,exp_last", [ @@ -961,21 +511,6 @@ def test_get_period_range_edges( expected = (exp_first, exp_last) assert result == expected - def test_sum_min_count(self): - # GH 19974 - index = date_range(start="2018", freq="ME", periods=6) - data = np.ones(6) - data[3:6] = np.nan - s = Series(data, index).to_period() - msg = "Resampling with a PeriodIndex is deprecated" - with tm.assert_produces_warning(FutureWarning, match=msg): - rs = s.resample("Q") - result = rs.sum(min_count=1) - expected = Series( - [3.0, np.nan], index=PeriodIndex(["2018Q1", "2018Q2"], freq="Q-DEC") - ) - tm.assert_series_equal(result, expected) - def test_resample_t_l_deprecated(self): # GH#52536 msg_t = "Invalid frequency: T" @@ -1051,16 +586,6 @@ def test_resample_frequency_ME_QE_YE_raises(frame_or_series, freq): obj.resample(freq) -def test_corner_cases_period(simple_period_range_series): - # miscellaneous test coverage - len0pts = simple_period_range_series("2007-01", "2010-05", freq="M")[:0] - # it works - msg = "Resampling with a PeriodIndex is deprecated" - with tm.assert_produces_warning(FutureWarning, match=msg): - result = len0pts.resample("Y-DEC").mean() - assert len(result) == 0 - - @pytest.mark.parametrize("freq", ["2BME", "2CBME", "2SME", "2BQE-FEB", "2BYE-MAR"]) def test_resample_frequency_invalid_freq(frame_or_series, freq): # GH#9586