diff --git a/doc/source/whatsnew/v1.3.0.rst b/doc/source/whatsnew/v1.3.0.rst index d357e4a633347..36457be9b2c46 100644 --- a/doc/source/whatsnew/v1.3.0.rst +++ b/doc/source/whatsnew/v1.3.0.rst @@ -674,6 +674,7 @@ Deprecations - Deprecated setting :attr:`Categorical._codes`, create a new :class:`Categorical` with the desired codes instead (:issue:`40606`) - Deprecated behavior of :meth:`DatetimeIndex.union` with mixed timezones; in a future version both will be cast to UTC instead of object dtype (:issue:`39328`) - Deprecated using ``usecols`` with out of bounds indices for ``read_csv`` with ``engine="c"`` (:issue:`25623`) +- Deprecated passing arguments as positional in :meth:`DataFrame.clip` and :meth:`Series.clip` (other than ``"upper"`` and ``"lower"``) (:issue:`41485`) - Deprecated special treatment of lists with first element a Categorical in the :class:`DataFrame` constructor; pass as ``pd.DataFrame({col: categorical, ...})`` instead (:issue:`38845`) - Deprecated passing arguments as positional (except for ``"method"``) in :meth:`DataFrame.interpolate` and :meth:`Series.interpolate` (:issue:`41485`) - Deprecated passing arguments (apart from ``value``) as positional in :meth:`DataFrame.fillna` and :meth:`Series.fillna` (:issue:`41485`) diff --git a/pandas/core/frame.py b/pandas/core/frame.py index 18ee1ad9bcd96..6a97a1e7b544d 100644 --- a/pandas/core/frame.py +++ b/pandas/core/frame.py @@ -10663,6 +10663,20 @@ def values(self) -> np.ndarray: self._consolidate_inplace() return self._mgr.as_array(transpose=True) + @deprecate_nonkeyword_arguments( + version=None, allowed_args=["self", "lower", "upper"] + ) + def clip( + self: DataFrame, + lower=None, + upper=None, + axis: Axis | None = None, + inplace: bool = False, + *args, + **kwargs, + ) -> DataFrame | None: + return super().clip(lower, upper, axis, inplace, *args, **kwargs) + @deprecate_nonkeyword_arguments(version=None, allowed_args=["self", "method"]) def interpolate( self: DataFrame, diff --git a/pandas/core/generic.py b/pandas/core/generic.py index 6d7c803685255..0cf31f9aa7586 100644 --- a/pandas/core/generic.py +++ b/pandas/core/generic.py @@ -7365,115 +7365,6 @@ def _clip_with_one_bound(self, threshold, method, axis, inplace): # GH 40420 return self.where(subset, threshold, axis=axis, inplace=inplace) - @overload - def clip( - self: FrameOrSeries, - lower=..., - upper=..., - axis: Axis | None = ..., - inplace: Literal[False] = ..., - *args, - **kwargs, - ) -> FrameOrSeries: - ... - - @overload - def clip( - self: FrameOrSeries, - lower, - *, - axis: Axis | None, - inplace: Literal[True], - **kwargs, - ) -> None: - ... - - @overload - def clip( - self: FrameOrSeries, - lower, - *, - inplace: Literal[True], - **kwargs, - ) -> None: - ... - - @overload - def clip( - self: FrameOrSeries, - *, - upper, - axis: Axis | None, - inplace: Literal[True], - **kwargs, - ) -> None: - ... - - @overload - def clip( - self: FrameOrSeries, - *, - upper, - inplace: Literal[True], - **kwargs, - ) -> None: - ... - - @overload - def clip( - self: FrameOrSeries, - *, - axis: Axis | None, - inplace: Literal[True], - **kwargs, - ) -> None: - ... - - @overload - def clip( - self: FrameOrSeries, - lower, - upper, - axis: Axis | None, - inplace: Literal[True], - *args, - **kwargs, - ) -> None: - ... - - @overload - def clip( - self: FrameOrSeries, - lower, - upper, - *, - inplace: Literal[True], - **kwargs, - ) -> None: - ... - - @overload - def clip( - self: FrameOrSeries, - *, - inplace: Literal[True], - **kwargs, - ) -> None: - ... - - @overload - def clip( - self: FrameOrSeries, - lower=..., - upper=..., - axis: Axis | None = ..., - inplace: bool_t = ..., - *args, - **kwargs, - ) -> FrameOrSeries | None: - ... - - @final def clip( self: FrameOrSeries, lower=None, diff --git a/pandas/core/series.py b/pandas/core/series.py index d8b7876028839..e4d1705e1d04c 100644 --- a/pandas/core/series.py +++ b/pandas/core/series.py @@ -5290,6 +5290,20 @@ def to_period(self, freq=None, copy=True) -> Series: self, method="to_period" ) + @deprecate_nonkeyword_arguments( + version=None, allowed_args=["self", "lower", "upper"] + ) + def clip( + self: Series, + lower=None, + upper=None, + axis: Axis | None = None, + inplace: bool = False, + *args, + **kwargs, + ) -> Series | None: + return super().clip(lower, upper, axis, inplace, *args, **kwargs) + @deprecate_nonkeyword_arguments(version=None, allowed_args=["self", "method"]) def interpolate( self: Series, diff --git a/pandas/tests/frame/methods/test_clip.py b/pandas/tests/frame/methods/test_clip.py index 6525109da4394..09b33831ed5ec 100644 --- a/pandas/tests/frame/methods/test_clip.py +++ b/pandas/tests/frame/methods/test_clip.py @@ -166,3 +166,15 @@ def test_clip_with_na_args(self, float_frame): result = df.clip(lower=t, axis=0) expected = DataFrame({"col_0": [9, -3, 0, 6, 5], "col_1": [2, -4, 6, 8, 3]}) tm.assert_frame_equal(result, expected) + + def test_clip_pos_args_deprecation(self): + # https://github.com/pandas-dev/pandas/issues/41485 + df = DataFrame({"a": [1, 2, 3]}) + msg = ( + r"In a future version of pandas all arguments of DataFrame.clip except " + r"for the arguments 'lower' and 'upper' will be keyword-only" + ) + with tm.assert_produces_warning(FutureWarning, match=msg): + result = df.clip(0, 1, 0) + expected = DataFrame({"a": [1, 1, 1]}) + tm.assert_frame_equal(result, expected) diff --git a/pandas/tests/series/methods/test_clip.py b/pandas/tests/series/methods/test_clip.py index 6185fe6c54fa4..7dbc194669a62 100644 --- a/pandas/tests/series/methods/test_clip.py +++ b/pandas/tests/series/methods/test_clip.py @@ -127,3 +127,15 @@ def test_clip_with_datetimes(self): ] ) tm.assert_series_equal(result, expected) + + def test_clip_pos_args_deprecation(self): + # https://github.com/pandas-dev/pandas/issues/41485 + ser = Series([1, 2, 3]) + msg = ( + r"In a future version of pandas all arguments of Series.clip except " + r"for the arguments 'lower' and 'upper' will be keyword-only" + ) + with tm.assert_produces_warning(FutureWarning, match=msg): + result = ser.clip(0, 1, 0) + expected = Series([1, 1, 1]) + tm.assert_series_equal(result, expected)