From f1ac08be9588e1d129425f6b14bf7c71473c22d3 Mon Sep 17 00:00:00 2001 From: Marco Gorelli Date: Sun, 16 May 2021 14:49:54 +0100 Subject: [PATCH 1/3] deprecate nonkeywordargs in interpolate --- doc/source/whatsnew/v1.3.0.rst | 1 + pandas/core/generic.py | 2 ++ pandas/tests/frame/methods/test_interpolate.py | 10 ++++++++++ pandas/tests/resample/test_datetime_index.py | 8 +++++--- pandas/tests/series/methods/test_interpolate.py | 10 ++++++++++ 5 files changed, 28 insertions(+), 3 deletions(-) diff --git a/doc/source/whatsnew/v1.3.0.rst b/doc/source/whatsnew/v1.3.0.rst index 622029adf357f..f881cf569118a 100644 --- a/doc/source/whatsnew/v1.3.0.rst +++ b/doc/source/whatsnew/v1.3.0.rst @@ -647,6 +647,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.interpolate` and :meth:`Series.interpolate` (:issue:`41485`) .. --------------------------------------------------------------------------- diff --git a/pandas/core/generic.py b/pandas/core/generic.py index a09cc0a6324c0..68112fadcf514 100644 --- a/pandas/core/generic.py +++ b/pandas/core/generic.py @@ -61,6 +61,7 @@ InvalidIndexError, ) from pandas.util._decorators import ( + deprecate_nonkeyword_arguments, doc, rewrite_axis_style_signature, ) @@ -6696,6 +6697,7 @@ def replace( else: return result.__finalize__(self, method="replace") + @deprecate_nonkeyword_arguments(version="2.0", allowed_args=["self"]) @final def interpolate( self: FrameOrSeries, diff --git a/pandas/tests/frame/methods/test_interpolate.py b/pandas/tests/frame/methods/test_interpolate.py index 5c6fcec887dfb..e55a25702319c 100644 --- a/pandas/tests/frame/methods/test_interpolate.py +++ b/pandas/tests/frame/methods/test_interpolate.py @@ -342,3 +342,13 @@ def test_interp_fillna_methods(self, axis, method): expected = df.fillna(axis=axis, method=method) result = df.interpolate(method=method, axis=axis) tm.assert_frame_equal(result, expected) + + def test_interpolate_pos_args_deprecation(self): + # https://github.com/pandas-dev/pandas/issues/41485 + df = DataFrame({"a": [1, 2, 3]}) + msg = ( + r"Starting with Pandas version 2\.0 all arguments of interpolate except " + r"for the argument 'self' will be keyword-only" + ) + with tm.assert_produces_warning(FutureWarning, match=msg): + df.interpolate(0) diff --git a/pandas/tests/resample/test_datetime_index.py b/pandas/tests/resample/test_datetime_index.py index 1c7aa5c444da9..155c509e44169 100644 --- a/pandas/tests/resample/test_datetime_index.py +++ b/pandas/tests/resample/test_datetime_index.py @@ -1026,12 +1026,14 @@ def test_resample_dtype_coercion(): df = {"a": [1, 3, 1, 4]} df = DataFrame(df, index=date_range("2017-01-01", "2017-01-04")) - expected = df.astype("float64").resample("H").mean()["a"].interpolate("cubic") + expected = ( + df.astype("float64").resample("H").mean()["a"].interpolate(method="cubic") + ) - result = df.resample("H")["a"].mean().interpolate("cubic") + result = df.resample("H")["a"].mean().interpolate(method="cubic") tm.assert_series_equal(result, expected) - result = df.resample("H").mean()["a"].interpolate("cubic") + result = df.resample("H").mean()["a"].interpolate(method="cubic") tm.assert_series_equal(result, expected) diff --git a/pandas/tests/series/methods/test_interpolate.py b/pandas/tests/series/methods/test_interpolate.py index 5686e6478772d..faaebccd5e8de 100644 --- a/pandas/tests/series/methods/test_interpolate.py +++ b/pandas/tests/series/methods/test_interpolate.py @@ -811,3 +811,13 @@ def test_interpolate_unsorted_index(self, ascending, expected_values): result = ts.sort_index(ascending=ascending).interpolate(method="index") expected = Series(data=expected_values, index=expected_values, dtype=float) tm.assert_series_equal(result, expected) + + def test_interpolate_pos_args_deprecation(self): + # https://github.com/pandas-dev/pandas/issues/41485 + ser = Series([1, 2, 3]) + msg = ( + r"Starting with Pandas version 2\.0 all arguments of interpolate except " + r"for the argument 'self' will be keyword-only" + ) + with tm.assert_produces_warning(FutureWarning, match=msg): + ser.interpolate(0) From a748a158dfdb632f7b1b5e863e53381e4afc7ebf Mon Sep 17 00:00:00 2001 From: Marco Gorelli Date: Mon, 17 May 2021 21:27:24 +0100 Subject: [PATCH 2/3] allow method to be positional --- doc/source/whatsnew/v1.3.0.rst | 2 +- pandas/core/generic.py | 2 +- pandas/tests/frame/methods/test_interpolate.py | 4 ++-- pandas/tests/resample/test_datetime_index.py | 8 +++----- pandas/tests/series/methods/test_interpolate.py | 4 ++-- 5 files changed, 9 insertions(+), 11 deletions(-) diff --git a/doc/source/whatsnew/v1.3.0.rst b/doc/source/whatsnew/v1.3.0.rst index f881cf569118a..7d376a90ae204 100644 --- a/doc/source/whatsnew/v1.3.0.rst +++ b/doc/source/whatsnew/v1.3.0.rst @@ -647,7 +647,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.interpolate` and :meth:`Series.interpolate` (:issue:`41485`) +- Deprecated passing arguments as positional (except for ``"method"``) in :meth:`DataFrame.interpolate` and :meth:`Series.interpolate` (:issue:`41485`) .. --------------------------------------------------------------------------- diff --git a/pandas/core/generic.py b/pandas/core/generic.py index 68112fadcf514..458524c812c8a 100644 --- a/pandas/core/generic.py +++ b/pandas/core/generic.py @@ -6697,7 +6697,7 @@ def replace( else: return result.__finalize__(self, method="replace") - @deprecate_nonkeyword_arguments(version="2.0", allowed_args=["self"]) + @deprecate_nonkeyword_arguments(version="2.0", allowed_args=["self", "method"]) @final def interpolate( self: FrameOrSeries, diff --git a/pandas/tests/frame/methods/test_interpolate.py b/pandas/tests/frame/methods/test_interpolate.py index e55a25702319c..fe95ac328f11e 100644 --- a/pandas/tests/frame/methods/test_interpolate.py +++ b/pandas/tests/frame/methods/test_interpolate.py @@ -348,7 +348,7 @@ def test_interpolate_pos_args_deprecation(self): df = DataFrame({"a": [1, 2, 3]}) msg = ( r"Starting with Pandas version 2\.0 all arguments of interpolate except " - r"for the argument 'self' will be keyword-only" + r"for the arguments 'self' and 'method' will be keyword-only" ) with tm.assert_produces_warning(FutureWarning, match=msg): - df.interpolate(0) + df.interpolate("pad", 0) diff --git a/pandas/tests/resample/test_datetime_index.py b/pandas/tests/resample/test_datetime_index.py index 155c509e44169..1c7aa5c444da9 100644 --- a/pandas/tests/resample/test_datetime_index.py +++ b/pandas/tests/resample/test_datetime_index.py @@ -1026,14 +1026,12 @@ def test_resample_dtype_coercion(): df = {"a": [1, 3, 1, 4]} df = DataFrame(df, index=date_range("2017-01-01", "2017-01-04")) - expected = ( - df.astype("float64").resample("H").mean()["a"].interpolate(method="cubic") - ) + expected = df.astype("float64").resample("H").mean()["a"].interpolate("cubic") - result = df.resample("H")["a"].mean().interpolate(method="cubic") + result = df.resample("H")["a"].mean().interpolate("cubic") tm.assert_series_equal(result, expected) - result = df.resample("H").mean()["a"].interpolate(method="cubic") + result = df.resample("H").mean()["a"].interpolate("cubic") tm.assert_series_equal(result, expected) diff --git a/pandas/tests/series/methods/test_interpolate.py b/pandas/tests/series/methods/test_interpolate.py index faaebccd5e8de..52a24e6670e7a 100644 --- a/pandas/tests/series/methods/test_interpolate.py +++ b/pandas/tests/series/methods/test_interpolate.py @@ -817,7 +817,7 @@ def test_interpolate_pos_args_deprecation(self): ser = Series([1, 2, 3]) msg = ( r"Starting with Pandas version 2\.0 all arguments of interpolate except " - r"for the argument 'self' will be keyword-only" + r"for the arguments 'self' and 'method' will be keyword-only" ) with tm.assert_produces_warning(FutureWarning, match=msg): - ser.interpolate(0) + ser.interpolate("pad", 0) From e1e094889c1e83ba277d52be3a641de33a540b7d Mon Sep 17 00:00:00 2001 From: Marco Gorelli Date: Tue, 18 May 2021 21:30:31 +0100 Subject: [PATCH 3/3] fixup after merge --- pandas/core/frame.py | 24 +++++++++++++++++++ pandas/core/generic.py | 3 --- pandas/core/series.py | 24 +++++++++++++++++++ .../tests/frame/methods/test_interpolate.py | 8 ++++--- .../tests/series/methods/test_interpolate.py | 8 ++++--- 5 files changed, 58 insertions(+), 9 deletions(-) diff --git a/pandas/core/frame.py b/pandas/core/frame.py index efefeb23445af..2a2ab371f63a1 100644 --- a/pandas/core/frame.py +++ b/pandas/core/frame.py @@ -77,6 +77,7 @@ Appender, Substitution, deprecate_kwarg, + deprecate_nonkeyword_arguments, doc, rewrite_axis_style_signature, ) @@ -10626,6 +10627,29 @@ def _values(self) -> np.ndarray: """internal implementation""" return self.values + @deprecate_nonkeyword_arguments(version=None, allowed_args=["self", "method"]) + def interpolate( + self: DataFrame, + method: str = "linear", + axis: Axis = 0, + limit: int | None = None, + inplace: bool = False, + limit_direction: str | None = None, + limit_area: str | None = None, + downcast: str | None = None, + **kwargs, + ) -> DataFrame | None: + return super().interpolate( + method, + axis, + limit, + inplace, + limit_direction, + limit_area, + downcast, + **kwargs, + ) + DataFrame._add_numeric_operations() diff --git a/pandas/core/generic.py b/pandas/core/generic.py index 458524c812c8a..3c69ba4e6bdf0 100644 --- a/pandas/core/generic.py +++ b/pandas/core/generic.py @@ -61,7 +61,6 @@ InvalidIndexError, ) from pandas.util._decorators import ( - deprecate_nonkeyword_arguments, doc, rewrite_axis_style_signature, ) @@ -6697,8 +6696,6 @@ def replace( else: return result.__finalize__(self, method="replace") - @deprecate_nonkeyword_arguments(version="2.0", allowed_args=["self", "method"]) - @final def interpolate( self: FrameOrSeries, method: str = "linear", diff --git a/pandas/core/series.py b/pandas/core/series.py index d0ff50cca5355..aaf37ad191e87 100644 --- a/pandas/core/series.py +++ b/pandas/core/series.py @@ -51,6 +51,7 @@ from pandas.util._decorators import ( Appender, Substitution, + deprecate_nonkeyword_arguments, doc, ) from pandas.util._validators import ( @@ -5256,6 +5257,29 @@ def to_period(self, freq=None, copy=True) -> Series: self, method="to_period" ) + @deprecate_nonkeyword_arguments(version=None, allowed_args=["self", "method"]) + def interpolate( + self: Series, + method: str = "linear", + axis: Axis = 0, + limit: int | None = None, + inplace: bool = False, + limit_direction: str | None = None, + limit_area: str | None = None, + downcast: str | None = None, + **kwargs, + ) -> Series | None: + return super().interpolate( + method, + axis, + limit, + inplace, + limit_direction, + limit_area, + downcast, + **kwargs, + ) + # ---------------------------------------------------------------------- # Add index _AXIS_ORDERS = ["index"] diff --git a/pandas/tests/frame/methods/test_interpolate.py b/pandas/tests/frame/methods/test_interpolate.py index fe95ac328f11e..d0551ffd5cffe 100644 --- a/pandas/tests/frame/methods/test_interpolate.py +++ b/pandas/tests/frame/methods/test_interpolate.py @@ -347,8 +347,10 @@ def test_interpolate_pos_args_deprecation(self): # https://github.com/pandas-dev/pandas/issues/41485 df = DataFrame({"a": [1, 2, 3]}) msg = ( - r"Starting with Pandas version 2\.0 all arguments of interpolate except " - r"for the arguments 'self' and 'method' will be keyword-only" + r"In a future version of pandas all arguments of DataFrame.interpolate " + r"except for the argument 'method' will be keyword-only" ) with tm.assert_produces_warning(FutureWarning, match=msg): - df.interpolate("pad", 0) + result = df.interpolate("pad", 0) + expected = DataFrame({"a": [1, 2, 3]}) + tm.assert_frame_equal(result, expected) diff --git a/pandas/tests/series/methods/test_interpolate.py b/pandas/tests/series/methods/test_interpolate.py index 52a24e6670e7a..8ca2d37016691 100644 --- a/pandas/tests/series/methods/test_interpolate.py +++ b/pandas/tests/series/methods/test_interpolate.py @@ -816,8 +816,10 @@ def test_interpolate_pos_args_deprecation(self): # https://github.com/pandas-dev/pandas/issues/41485 ser = Series([1, 2, 3]) msg = ( - r"Starting with Pandas version 2\.0 all arguments of interpolate except " - r"for the arguments 'self' and 'method' will be keyword-only" + r"In a future version of pandas all arguments of Series.interpolate except " + r"for the argument 'method' will be keyword-only" ) with tm.assert_produces_warning(FutureWarning, match=msg): - ser.interpolate("pad", 0) + result = ser.interpolate("pad", 0) + expected = Series([1, 2, 3]) + tm.assert_series_equal(result, expected)