diff --git a/doc/source/whatsnew/v2.1.0.rst b/doc/source/whatsnew/v2.1.0.rst index db900ddd1f85b..0cb1641e40e05 100644 --- a/doc/source/whatsnew/v2.1.0.rst +++ b/doc/source/whatsnew/v2.1.0.rst @@ -107,6 +107,7 @@ Deprecations - Deprecated accepting slices in :meth:`DataFrame.take`, call ``obj[slicer]`` or pass a sequence of integers instead (:issue:`51539`) - Deprecated ``axis=1`` in :meth:`DataFrame.ewm`, :meth:`DataFrame.rolling`, :meth:`DataFrame.expanding`, transpose before calling the method instead (:issue:`51778`) - Deprecated the ``axis`` keyword in :meth:`DataFrame.ewm`, :meth:`Series.ewm`, :meth:`DataFrame.rolling`, :meth:`Series.rolling`, :meth:`DataFrame.expanding`, :meth:`Series.expanding` (:issue:`51778`) +- Deprecated the ``axis`` keyword in :meth:`DataFrame.resample`, :meth:`Series.resample` (:issue:`51778`) - Deprecated 'method', 'limit', and 'fill_axis' keywords in :meth:`DataFrame.align` and :meth:`Series.align`, explicitly call ``fillna`` on the alignment results instead (:issue:`51856`) - Deprecated the 'axis' keyword in :meth:`.GroupBy.idxmax`, :meth:`.GroupBy.idxmin`, :meth:`.GroupBy.fillna`, :meth:`.GroupBy.take`, :meth:`.GroupBy.skew`, :meth:`.GroupBy.rank`, :meth:`.GroupBy.cumprod`, :meth:`.GroupBy.cumsum`, :meth:`.GroupBy.cummax`, :meth:`.GroupBy.cummin`, :meth:`.GroupBy.pct_change`, :meth:`GroupBy.diff`, :meth:`.GroupBy.shift`, and :meth:`DataFrameGroupBy.corrwith`; for ``axis=1`` operate on the underlying :class:`DataFrame` instead (:issue:`50405`, :issue:`51046`) - diff --git a/pandas/core/frame.py b/pandas/core/frame.py index a2e3b6fc10e43..85a224636dabc 100644 --- a/pandas/core/frame.py +++ b/pandas/core/frame.py @@ -11418,7 +11418,7 @@ def asfreq( def resample( self, rule, - axis: Axis = 0, + axis: Axis | lib.NoDefault = lib.no_default, closed: str | None = None, label: str | None = None, convention: str = "start", diff --git a/pandas/core/generic.py b/pandas/core/generic.py index d621a1c68b0f8..aa04c601a81cd 100644 --- a/pandas/core/generic.py +++ b/pandas/core/generic.py @@ -8555,7 +8555,7 @@ def between_time( def resample( self, rule, - axis: Axis = 0, + axis: Axis | lib.NoDefault = lib.no_default, closed: str | None = None, label: str | None = None, convention: str = "start", @@ -8582,6 +8582,9 @@ def resample( Which axis to use for up- or down-sampling. For `Series` this parameter is unused and defaults to 0. Must be `DatetimeIndex`, `TimedeltaIndex` or `PeriodIndex`. + + .. deprecated:: 2.0.0 + Use frame.T.resample(...) instead. closed : {{'right', 'left'}}, default None Which side of bin interval is closed. The default is 'left' for all frequency offsets except for 'M', 'A', 'Q', 'BM', @@ -8938,7 +8941,25 @@ def resample( """ from pandas.core.resample import get_resampler - axis = self._get_axis_number(axis) + if axis is not lib.no_default: + axis = self._get_axis_number(axis) + if axis == 1: + warnings.warn( + "DataFrame.resample with axis=1 is deprecated. Do " + "`frame.T.resample(...)` without axis instead.", + FutureWarning, + stacklevel=find_stack_level(), + ) + else: + warnings.warn( + "The 'axis' keyword in DataFrame.resample is deprecated and " + "will be removed in a future version.", + FutureWarning, + stacklevel=find_stack_level(), + ) + else: + axis = 0 + return get_resampler( cast("Series | DataFrame", self), freq=rule, diff --git a/pandas/core/series.py b/pandas/core/series.py index f8875555fdf97..8859b97874cef 100644 --- a/pandas/core/series.py +++ b/pandas/core/series.py @@ -5570,7 +5570,7 @@ def asfreq( def resample( self, rule, - axis: Axis = 0, + axis: Axis | lib.NoDefault = lib.no_default, closed: str | None = None, label: str | None = None, convention: str = "start", @@ -5581,6 +5581,14 @@ def resample( offset: TimedeltaConvertibleTypes | None = None, group_keys: bool = False, ) -> Resampler: + if axis is not lib.no_default: + warnings.warn( + "Series resample axis keyword is deprecated and will be removed in a " + "future version.", + FutureWarning, + stacklevel=find_stack_level(), + ) + return super().resample( rule=rule, axis=axis, diff --git a/pandas/tests/resample/test_datetime_index.py b/pandas/tests/resample/test_datetime_index.py index 01e11c779e957..cbf530e995c43 100644 --- a/pandas/tests/resample/test_datetime_index.py +++ b/pandas/tests/resample/test_datetime_index.py @@ -641,7 +641,10 @@ def test_resample_dup_index(): columns=[Period(year=2000, month=i + 1, freq="M") for i in range(12)], ) df.iloc[3, :] = np.nan - result = df.resample("Q", axis=1).mean() + warning_msg = "DataFrame.resample with axis=1 is deprecated." + with tm.assert_produces_warning(FutureWarning, match=warning_msg): + result = df.resample("Q", axis=1).mean() + msg = "DataFrame.groupby with axis=1 is deprecated" with tm.assert_produces_warning(FutureWarning, match=msg): expected = df.groupby(lambda x: int((x.month - 1) / 3), axis=1).mean() @@ -729,7 +732,9 @@ def test_resample_axis1(unit): rng = date_range("1/1/2000", "2/29/2000").as_unit(unit) df = DataFrame(np.random.randn(3, len(rng)), columns=rng, index=["a", "b", "c"]) - result = df.resample("M", axis=1).mean() + warning_msg = "DataFrame.resample with axis=1 is deprecated." + with tm.assert_produces_warning(FutureWarning, match=warning_msg): + result = df.resample("M", axis=1).mean() expected = df.T.resample("M").mean().T tm.assert_frame_equal(result, expected) diff --git a/pandas/tests/resample/test_resample_api.py b/pandas/tests/resample/test_resample_api.py index b36a6295248cd..1635c79de9abb 100644 --- a/pandas/tests/resample/test_resample_api.py +++ b/pandas/tests/resample/test_resample_api.py @@ -568,9 +568,13 @@ def test_multi_agg_axis_1_raises(func): index = date_range(datetime(2005, 1, 1), datetime(2005, 1, 10), freq="D") index.name = "date" df = DataFrame(np.random.rand(10, 2), columns=list("AB"), index=index).T - res = df.resample("M", axis=1) - with pytest.raises(NotImplementedError, match="axis other than 0 is not supported"): - res.agg(func) + warning_msg = "DataFrame.resample with axis=1 is deprecated." + with tm.assert_produces_warning(FutureWarning, match=warning_msg): + res = df.resample("M", axis=1) + with pytest.raises( + NotImplementedError, match="axis other than 0 is not supported" + ): + res.agg(func) def test_agg_nested_dicts(): @@ -971,3 +975,33 @@ def test_args_kwargs_depr(method, raises): with tm.assert_produces_warning(FutureWarning, match=warn_msg): with pytest.raises(TypeError, match=error_msg_type): func(*args, 1, 2, 3) + + +def test_df_axis_param_depr(): + np.random.seed(1234) + index = date_range(datetime(2005, 1, 1), datetime(2005, 1, 10), freq="D") + index.name = "date" + df = DataFrame(np.random.rand(10, 2), columns=list("AB"), index=index).T + + # Deprication error when axis=1 is explicitly passed + warning_msg = "DataFrame.resample with axis=1 is deprecated." + with tm.assert_produces_warning(FutureWarning, match=warning_msg): + df.resample("M", axis=1) + + # Deprication error when axis=0 is explicitly passed + df = df.T + warning_msg = ( + "The 'axis' keyword in DataFrame.resample is deprecated and " + "will be removed in a future version." + ) + with tm.assert_produces_warning(FutureWarning, match=warning_msg): + df.resample("M", axis=0) + + +def test_series_axis_param_depr(): + warning_msg = ( + "Series resample axis keyword is deprecated and will be removed in a " + "future version." + ) + with tm.assert_produces_warning(FutureWarning, match=warning_msg): + test_series.resample("H", axis=0)