From bf16a0c17e55e9b546de7e1b338d46919d0eb279 Mon Sep 17 00:00:00 2001 From: Patrick Hoefler Date: Thu, 29 Dec 2022 00:11:08 +0100 Subject: [PATCH 1/3] ENH: Add lazy copy for truncate --- pandas/core/generic.py | 6 +++--- pandas/tests/copy_view/test_methods.py | 24 ++++++++++++++++++++++++ 2 files changed, 27 insertions(+), 3 deletions(-) diff --git a/pandas/core/generic.py b/pandas/core/generic.py index c893e9ce3d9a9..ac3ca7e5401e4 100644 --- a/pandas/core/generic.py +++ b/pandas/core/generic.py @@ -9940,7 +9940,7 @@ def truncate( before=None, after=None, axis: Axis | None = None, - copy: bool_t = True, + copy: bool_t | None = None, ) -> NDFrameT: """ Truncate a Series or DataFrame before and after some index value. @@ -10091,8 +10091,8 @@ def truncate( if isinstance(ax, MultiIndex): setattr(result, self._get_axis_name(axis), ax.truncate(before, after)) - if copy: - result = result.copy() + if copy or copy is None: + result = result.copy(deep=copy) return result diff --git a/pandas/tests/copy_view/test_methods.py b/pandas/tests/copy_view/test_methods.py index 878f1d8089d33..3c427657bf207 100644 --- a/pandas/tests/copy_view/test_methods.py +++ b/pandas/tests/copy_view/test_methods.py @@ -369,6 +369,30 @@ def test_head_tail(method, using_copy_on_write): tm.assert_frame_equal(df, df_orig) +@pytest.mark.parametrize( + "kwargs", + [ + {"before": "a", "after": "b", "axis": 1}, + {"before": 0, "after": 1, "axis": 0}, + ], +) +def test_truncate(using_copy_on_write, kwargs): + df = DataFrame({"a": [1, 2, 3], "b": 1, "c": 2}) + df_orig = df.copy() + df2 = df.truncate(**kwargs) + df2._mgr._verify_integrity() + + if using_copy_on_write: + assert np.shares_memory(get_array(df2, "a"), get_array(df, "a")) + else: + assert not np.shares_memory(get_array(df2, "a"), get_array(df, "a")) + + df2.iloc[0, 0] = 0 + if using_copy_on_write: + assert not np.shares_memory(get_array(df2, "a"), get_array(df, "a")) + tm.assert_frame_equal(df, df_orig) + + @pytest.mark.parametrize("method", ["assign", "drop_duplicates"]) def test_assign_drop_duplicates(using_copy_on_write, method): df = DataFrame({"a": [1, 2, 3]}) From 8976062e6c7bc717cc08dbb7b1f32530d2acc2ba Mon Sep 17 00:00:00 2001 From: Patrick Hoefler Date: Thu, 29 Dec 2022 21:11:08 +0100 Subject: [PATCH 2/3] Remove test --- pandas/tests/frame/methods/test_truncate.py | 6 ------ 1 file changed, 6 deletions(-) diff --git a/pandas/tests/frame/methods/test_truncate.py b/pandas/tests/frame/methods/test_truncate.py index bfee3edc085d8..21f0664707ebe 100644 --- a/pandas/tests/frame/methods/test_truncate.py +++ b/pandas/tests/frame/methods/test_truncate.py @@ -66,12 +66,6 @@ def test_truncate(self, datetime_frame, frame_or_series): before=ts.index[-1] - ts.index.freq, after=ts.index[0] + ts.index.freq ) - def test_truncate_copy(self, datetime_frame): - index = datetime_frame.index - truncated = datetime_frame.truncate(index[5], index[10]) - truncated.values[:] = 5.0 - assert not (datetime_frame.values[5:11] == 5).any() - def test_truncate_nonsortedindex(self, frame_or_series): # GH#17935 From b2c467c25fa15172c2de3034b68a2d659bd67b93 Mon Sep 17 00:00:00 2001 From: Patrick Hoefler Date: Tue, 3 Jan 2023 12:05:31 +0100 Subject: [PATCH 3/3] Adjust condition --- pandas/core/generic.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/pandas/core/generic.py b/pandas/core/generic.py index 49eac6d565bf1..f6dfc7d3b076a 100644 --- a/pandas/core/generic.py +++ b/pandas/core/generic.py @@ -159,6 +159,7 @@ SingleArrayManager, ) from pandas.core.internals.construction import mgr_to_mgr +from pandas.core.internals.managers import _using_copy_on_write from pandas.core.missing import ( clean_fill_method, clean_reindex_fill_method, @@ -10098,7 +10099,7 @@ def truncate( if isinstance(ax, MultiIndex): setattr(result, self._get_axis_name(axis), ax.truncate(before, after)) - if copy or copy is None: + if copy or (copy is None and not _using_copy_on_write()): result = result.copy(deep=copy) return result