diff --git a/pandas/core/internals/managers.py b/pandas/core/internals/managers.py index 81c5810d29456..ff80cccaa20d3 100644 --- a/pandas/core/internals/managers.py +++ b/pandas/core/internals/managers.py @@ -409,8 +409,15 @@ def diff(self: T, n: int, axis: AxisInt) -> T: axis = self._normalize_axis(axis) return self.apply("diff", n=n, axis=axis) - def interpolate(self: T, **kwargs) -> T: - return self.apply("interpolate", **kwargs) + def interpolate(self: T, inplace: bool, **kwargs) -> T: + if inplace: + # TODO(CoW) can be optimized to only copy those blocks that have refs + if using_copy_on_write() and any( + not self._has_no_reference_block(i) for i in range(len(self.blocks)) + ): + self = self.copy() + + return self.apply("interpolate", inplace=inplace, **kwargs) def shift(self: T, periods: int, axis: AxisInt, fill_value) -> T: axis = self._normalize_axis(axis) diff --git a/pandas/tests/copy_view/test_methods.py b/pandas/tests/copy_view/test_methods.py index fbd4bbfb38c27..26038725c544f 100644 --- a/pandas/tests/copy_view/test_methods.py +++ b/pandas/tests/copy_view/test_methods.py @@ -1194,6 +1194,22 @@ def test_asfreq_noop(using_copy_on_write): tm.assert_frame_equal(df, df_orig) +def test_interpolate_creates_copy(using_copy_on_write): + # GH#51126 + df = DataFrame({"a": [1.5, np.nan, 3]}) + view = df[:] + expected = df.copy() + + df.ffill(inplace=True) + df.iloc[0, 0] = 100.5 + + if using_copy_on_write: + tm.assert_frame_equal(view, expected) + else: + expected = DataFrame({"a": [100.5, 1.5, 3]}) + tm.assert_frame_equal(view, expected) + + def test_isetitem(using_copy_on_write): df = DataFrame({"a": [1, 2, 3], "b": [4, 5, 6], "c": [7, 8, 9]}) df_orig = df.copy()