From 7eb44837ade6d68e65819307195b171b612a46c8 Mon Sep 17 00:00:00 2001 From: Carlo Barth Date: Mon, 27 May 2024 18:31:00 +0200 Subject: [PATCH 1/3] feat!: Removes `inplace` option for `pandas.core.resample.Resampler.interpolate`. Fixes / cleans up related test cases. --- pandas/core/resample.py | 5 +- pandas/tests/copy_view/test_interp_fillna.py | 6 +- .../tests/frame/methods/test_interpolate.py | 60 +------------------ pandas/tests/generic/test_frame.py | 3 - 4 files changed, 8 insertions(+), 66 deletions(-) diff --git a/pandas/core/resample.py b/pandas/core/resample.py index ccbe25fdae841..0ed644618a746 100644 --- a/pandas/core/resample.py +++ b/pandas/core/resample.py @@ -762,7 +762,6 @@ def interpolate( *, axis: Axis = 0, limit: int | None = None, - inplace: bool = False, limit_direction: Literal["forward", "backward", "both"] = "forward", limit_area=None, downcast=lib.no_default, @@ -909,6 +908,8 @@ def interpolate( ``07:00:00`` and ``07:00:02``. """ assert downcast is lib.no_default # just checking coverage + if kwargs.get("inplace"): + raise ValueError("The argument 'inplace' is no longer supported.") result = self._upsample("asfreq") # If the original data has timestamps which are not aligned with the @@ -942,7 +943,7 @@ def interpolate( method=method, axis=axis, limit=limit, - inplace=inplace, + inplace=False, limit_direction=limit_direction, limit_area=limit_area, downcast=downcast, diff --git a/pandas/tests/copy_view/test_interp_fillna.py b/pandas/tests/copy_view/test_interp_fillna.py index abd87162ec32e..9e506cb20b36f 100644 --- a/pandas/tests/copy_view/test_interp_fillna.py +++ b/pandas/tests/copy_view/test_interp_fillna.py @@ -132,7 +132,7 @@ def test_interpolate_object_convert_copies(): arr_a = get_array(df, "a") msg = "Can not interpolate with method=pad" with pytest.raises(ValueError, match=msg): - df.interpolate(method="pad", inplace=True, downcast="infer") + df.interpolate(method="pad", inplace=False, downcast="infer") assert df._mgr._has_no_reference(0) assert np.shares_memory(arr_a, get_array(df, "a")) @@ -146,7 +146,7 @@ def test_interpolate_downcast_reference_triggers_copy(): msg = "Can not interpolate with method=pad" with pytest.raises(ValueError, match=msg): - df.interpolate(method="pad", inplace=True, downcast="infer") + df.interpolate(method="pad", inplace=False, downcast="infer") assert df._mgr._has_no_reference(0) assert not np.shares_memory(arr_a, get_array(df, "a")) @@ -285,7 +285,7 @@ def test_fillna_chained_assignment(): tm.assert_frame_equal(df, df_orig) -@pytest.mark.parametrize("func", ["interpolate", "ffill", "bfill"]) +@pytest.mark.parametrize("func", ["ffill", "bfill"]) def test_interpolate_chained_assignment(func): df = DataFrame({"a": [1, np.nan, 2], "b": 1}) df_orig = df.copy() diff --git a/pandas/tests/frame/methods/test_interpolate.py b/pandas/tests/frame/methods/test_interpolate.py index cdb9ff8a67b6b..bc097e6ddfbf8 100644 --- a/pandas/tests/frame/methods/test_interpolate.py +++ b/pandas/tests/frame/methods/test_interpolate.py @@ -51,19 +51,6 @@ def test_interpolate_datetimelike_values(self, frame_or_series): expected_td = frame_or_series(orig - orig[0]) tm.assert_equal(res_td, expected_td) - def test_interpolate_inplace(self, frame_or_series, request): - # GH#44749 - obj = frame_or_series([1, np.nan, 2]) - orig = obj.values - - obj.interpolate(inplace=True) - expected = frame_or_series([1, 1.5, 2]) - tm.assert_equal(obj, expected) - - # check we operated *actually* inplace - assert np.shares_memory(orig, obj.values) - assert orig.squeeze()[1] == 1.5 - @pytest.mark.xfail( using_pyarrow_string_dtype(), reason="interpolate doesn't work for string" ) @@ -80,15 +67,6 @@ def test_interp_basic(self): with pytest.raises(TypeError, match=msg): df.interpolate() - cvalues = df["C"]._values - dvalues = df["D"].values - with pytest.raises(TypeError, match=msg): - df.interpolate(inplace=True) - - # check we DID operate inplace - assert np.shares_memory(df["C"]._values, cvalues) - assert np.shares_memory(df["D"]._values, dvalues) - @pytest.mark.xfail( using_pyarrow_string_dtype(), reason="interpolate doesn't work for string" ) @@ -307,26 +285,6 @@ def test_interp_raise_on_all_object_dtype(self): with pytest.raises(TypeError, match=msg): df.interpolate() - def test_interp_inplace(self): - df = DataFrame({"a": [1.0, 2.0, np.nan, 4.0]}) - expected = df.copy() - result = df.copy() - - with tm.raises_chained_assignment_error(): - return_value = result["a"].interpolate(inplace=True) - assert return_value is None - tm.assert_frame_equal(result, expected) - - def test_interp_inplace_row(self): - # GH 10395 - result = DataFrame( - {"a": [1.0, 2.0, 3.0, 4.0], "b": [np.nan, 2.0, 3.0, 4.0], "c": [3, 2, 2, 2]} - ) - expected = result.interpolate(method="linear", axis=1, inplace=False) - return_value = result.interpolate(method="linear", axis=1, inplace=True) - assert return_value is None - tm.assert_frame_equal(result, expected) - def test_interp_ignore_all_good(self): # GH df = DataFrame( @@ -352,19 +310,6 @@ def test_interp_ignore_all_good(self): result = df[["B", "D"]].interpolate() tm.assert_frame_equal(result, df[["B", "D"]]) - def test_interp_time_inplace_axis(self): - # GH 9687 - periods = 5 - idx = date_range(start="2014-01-01", periods=periods) - data = np.random.default_rng(2).random((periods, periods)) - data[data < 0.5] = np.nan - expected = DataFrame(index=idx, columns=idx, data=data) - - result = expected.interpolate(axis=0, method="time") - return_value = expected.interpolate(axis=0, method="time", inplace=True) - assert return_value is None - tm.assert_frame_equal(result, expected) - @pytest.mark.parametrize("axis_name, axis_number", [("index", 0), ("columns", 1)]) def test_interp_string_axis(self, axis_name, axis_number): # https://github.com/pandas-dev/pandas/issues/25190 @@ -400,9 +345,8 @@ def test_interpolate_empty_df(self): # GH#53199 df = DataFrame() expected = df.copy() - result = df.interpolate(inplace=True) - assert result is None - tm.assert_frame_equal(df, expected) + result = df.interpolate() + tm.assert_frame_equal(result, expected) def test_interpolate_ea(self, any_int_ea_dtype): # GH#55347 diff --git a/pandas/tests/generic/test_frame.py b/pandas/tests/generic/test_frame.py index 1d0f491529b56..d6c654343573b 100644 --- a/pandas/tests/generic/test_frame.py +++ b/pandas/tests/generic/test_frame.py @@ -160,9 +160,6 @@ def test_validate_bool_args(self, value): with pytest.raises(ValueError, match=msg): df.copy().replace(to_replace=1, value=7, inplace=value) - with pytest.raises(ValueError, match=msg): - df.copy().interpolate(inplace=value) - with pytest.raises(ValueError, match=msg): df.copy()._where(cond=df.a > 2, inplace=value) From 479e1f03927e79983a16ee7d68a699c6270eee21 Mon Sep 17 00:00:00 2001 From: Carlo Barth Date: Mon, 27 May 2024 19:22:31 +0200 Subject: [PATCH 2/3] fix: Fixes doc string of `pandas.core.resample.Resampler.interpolate`. Adds breaking API change description to whatsnew. --- doc/source/whatsnew/v3.0.0.rst | 1 + pandas/core/resample.py | 2 -- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/doc/source/whatsnew/v3.0.0.rst b/doc/source/whatsnew/v3.0.0.rst index 6a6abcf2d48fe..33503c34df993 100644 --- a/doc/source/whatsnew/v3.0.0.rst +++ b/doc/source/whatsnew/v3.0.0.rst @@ -160,6 +160,7 @@ Other API changes - 3rd party ``py.path`` objects are no longer explicitly supported in IO methods. Use :py:class:`pathlib.Path` objects instead (:issue:`57091`) - :func:`read_table`'s ``parse_dates`` argument defaults to ``None`` to improve consistency with :func:`read_csv` (:issue:`57476`) - Made ``dtype`` a required argument in :meth:`ExtensionArray._from_sequence_of_strings` (:issue:`56519`) +- Removed ``inplace`` argument in :meth:`Resampler.interpolate`. (:issue:`58690`) - Updated :meth:`DataFrame.to_excel` so that the output spreadsheet has no styling. Custom styling can still be done using :meth:`Styler.to_excel` (:issue:`54154`) - pickle and HDF (``.h5``) files created with Python 2 are no longer explicitly supported (:issue:`57387`) - pickled objects from pandas version less than ``1.0.0`` are no longer supported (:issue:`57155`) diff --git a/pandas/core/resample.py b/pandas/core/resample.py index 0ed644618a746..32bcba59f5170 100644 --- a/pandas/core/resample.py +++ b/pandas/core/resample.py @@ -807,8 +807,6 @@ def interpolate( limit : int, optional Maximum number of consecutive NaNs to fill. Must be greater than 0. - inplace : bool, default False - Update the data in place if possible. limit_direction : {{'forward', 'backward', 'both'}}, Optional Consecutive NaNs will be filled in this direction. From 9f0a9a0ec8633ee2c13e0a9596f923cd7a473964 Mon Sep 17 00:00:00 2001 From: Carlo Barth Date: Wed, 5 Jun 2024 18:30:59 +0200 Subject: [PATCH 3/3] fix: Reverts wrongly adjusted test case to use inplace on `interpolate` without prior resample. --- pandas/tests/copy_view/test_interp_fillna.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pandas/tests/copy_view/test_interp_fillna.py b/pandas/tests/copy_view/test_interp_fillna.py index 9e506cb20b36f..1bf6562119126 100644 --- a/pandas/tests/copy_view/test_interp_fillna.py +++ b/pandas/tests/copy_view/test_interp_fillna.py @@ -132,7 +132,7 @@ def test_interpolate_object_convert_copies(): arr_a = get_array(df, "a") msg = "Can not interpolate with method=pad" with pytest.raises(ValueError, match=msg): - df.interpolate(method="pad", inplace=False, downcast="infer") + df.interpolate(method="pad", inplace=True, downcast="infer") assert df._mgr._has_no_reference(0) assert np.shares_memory(arr_a, get_array(df, "a"))