From e0915431e2a76f6a1a4580573bf5bbe417e80639 Mon Sep 17 00:00:00 2001 From: Patrick Hoefler Date: Fri, 17 Mar 2023 00:50:57 +0100 Subject: [PATCH 1/3] CoW: Optimize Series.reset_index to make lazy copy --- pandas/core/series.py | 3 +++ pandas/tests/copy_view/test_methods.py | 14 ++++++++++++++ 2 files changed, 17 insertions(+) diff --git a/pandas/core/series.py b/pandas/core/series.py index b0958869c67f3..4cb0a5e22d4da 100644 --- a/pandas/core/series.py +++ b/pandas/core/series.py @@ -1550,6 +1550,9 @@ def reset_index( if inplace: self.index = new_index + elif using_copy_on_write(): + new_ser = self._constructor(self, index=new_index, copy=False) + return new_ser.__finalize__(self, method="reset_index") else: return self._constructor( self._values.copy(), index=new_index, copy=False diff --git a/pandas/tests/copy_view/test_methods.py b/pandas/tests/copy_view/test_methods.py index cd49763bc2186..3caa7a1d366fb 100644 --- a/pandas/tests/copy_view/test_methods.py +++ b/pandas/tests/copy_view/test_methods.py @@ -233,6 +233,20 @@ def test_reset_index(using_copy_on_write): tm.assert_frame_equal(df, df_orig) +def test_reset_index_series_drop(using_copy_on_write): + ser = Series([1, 2]) + ser_orig = ser.copy() + ser2 = ser.reset_index(drop=True) + if using_copy_on_write: + assert np.shares_memory(get_array(ser), get_array(ser2)) + assert not ser._mgr._has_no_reference(0) + else: + assert not np.shares_memory(get_array(ser), get_array(ser2)) + + ser2.iloc[0] = 100 + tm.assert_series_equal(ser, ser_orig) + + def test_rename_columns(using_copy_on_write): # Case: renaming columns returns a new dataframe # + afterwards modifying the result From 60b131ff9236e3504c77ebc665a1682b1c3a26cb Mon Sep 17 00:00:00 2001 From: Patrick Hoefler Date: Fri, 17 Mar 2023 00:53:13 +0100 Subject: [PATCH 2/3] Update --- pandas/core/series.py | 3 ++- pandas/tests/copy_view/test_methods.py | 5 +++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/pandas/core/series.py b/pandas/core/series.py index 4cb0a5e22d4da..b391a1e2bbbd6 100644 --- a/pandas/core/series.py +++ b/pandas/core/series.py @@ -1551,7 +1551,8 @@ def reset_index( if inplace: self.index = new_index elif using_copy_on_write(): - new_ser = self._constructor(self, index=new_index, copy=False) + new_ser = self._constructor(self, copy=False) + new_ser.index = new_index return new_ser.__finalize__(self, method="reset_index") else: return self._constructor( diff --git a/pandas/tests/copy_view/test_methods.py b/pandas/tests/copy_view/test_methods.py index 3caa7a1d366fb..1d8f1dea7d478 100644 --- a/pandas/tests/copy_view/test_methods.py +++ b/pandas/tests/copy_view/test_methods.py @@ -233,8 +233,9 @@ def test_reset_index(using_copy_on_write): tm.assert_frame_equal(df, df_orig) -def test_reset_index_series_drop(using_copy_on_write): - ser = Series([1, 2]) +@pytest.mark.parametrize("index", [pd.RangeIndex(0, 2), Index([1, 2])]) +def test_reset_index_series_drop(using_copy_on_write, index): + ser = Series([1, 2], index=index) ser_orig = ser.copy() ser2 = ser.reset_index(drop=True) if using_copy_on_write: From b71f453d5193b693a01911d6f04cc2909da0843b Mon Sep 17 00:00:00 2001 From: Patrick Hoefler Date: Fri, 17 Mar 2023 00:54:31 +0100 Subject: [PATCH 3/3] Update --- pandas/core/series.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pandas/core/series.py b/pandas/core/series.py index b391a1e2bbbd6..515b904da2b9c 100644 --- a/pandas/core/series.py +++ b/pandas/core/series.py @@ -1551,7 +1551,7 @@ def reset_index( if inplace: self.index = new_index elif using_copy_on_write(): - new_ser = self._constructor(self, copy=False) + new_ser = self.copy(deep=False) new_ser.index = new_index return new_ser.__finalize__(self, method="reset_index") else: