From f5ccde0aac2bf0dc5899937501b487d7512bf45d Mon Sep 17 00:00:00 2001 From: Patrick Hoefler Date: Wed, 15 Mar 2023 22:07:45 +0100 Subject: [PATCH 1/2] CoW: Series with MultiIndex with tuples does not respect CoW --- pandas/core/series.py | 7 ++++--- pandas/tests/copy_view/test_indexing.py | 16 ++++++++++++++++ 2 files changed, 20 insertions(+), 3 deletions(-) diff --git a/pandas/core/series.py b/pandas/core/series.py index 7050dd0ffb7df..229cadad3746a 100644 --- a/pandas/core/series.py +++ b/pandas/core/series.py @@ -1044,9 +1044,10 @@ def _get_values_tuple(self, key: tuple): # If key is contained, would have returned by now indexer, new_index = self.index.get_loc_level(key) - return self._constructor(self._values[indexer], index=new_index).__finalize__( - self - ) + result = self._constructor(self._values[indexer], index=new_index) + if using_copy_on_write() and isinstance(indexer, slice): + result._mgr.add_references(self._mgr) # type: ignore[arg-type] + return result.__finalize__(self) def _get_values(self, indexer: slice | npt.NDArray[np.bool_]) -> Series: new_mgr = self._mgr.getitem_mgr(indexer) diff --git a/pandas/tests/copy_view/test_indexing.py b/pandas/tests/copy_view/test_indexing.py index 17b9c16ce1e15..24045c404bc86 100644 --- a/pandas/tests/copy_view/test_indexing.py +++ b/pandas/tests/copy_view/test_indexing.py @@ -1049,3 +1049,19 @@ def test_getitem_midx_slice(using_copy_on_write, using_array_manager): if using_copy_on_write: new_df.iloc[0, 0] = 100 tm.assert_frame_equal(df_orig, df) + + +def test_series_midx_tuples_slice(using_copy_on_write): + ser = Series( + [1, 2, 3], + index=pd.MultiIndex.from_tuples([((1, 2), 3), ((1, 2), 4), ((2, 3), 4)]), + ) + result = ser[(1, 2)] + assert np.shares_memory(get_array(ser), get_array(result)) + result.iloc[0] = 100 + if using_copy_on_write: + expected = Series( + [1, 2, 3], + index=pd.MultiIndex.from_tuples([((1, 2), 3), ((1, 2), 4), ((2, 3), 4)]), + ) + tm.assert_series_equal(ser, expected) From 2416a9bc8a5fb3a952d35faf8246f5ff1849f839 Mon Sep 17 00:00:00 2001 From: Patrick Hoefler Date: Wed, 15 Mar 2023 23:09:00 +0100 Subject: [PATCH 2/2] Fix naming --- pandas/core/series.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/pandas/core/series.py b/pandas/core/series.py index 229cadad3746a..1bdf495c433c7 100644 --- a/pandas/core/series.py +++ b/pandas/core/series.py @@ -1044,10 +1044,10 @@ def _get_values_tuple(self, key: tuple): # If key is contained, would have returned by now indexer, new_index = self.index.get_loc_level(key) - result = self._constructor(self._values[indexer], index=new_index) + new_ser = self._constructor(self._values[indexer], index=new_index) if using_copy_on_write() and isinstance(indexer, slice): - result._mgr.add_references(self._mgr) # type: ignore[arg-type] - return result.__finalize__(self) + new_ser._mgr.add_references(self._mgr) # type: ignore[arg-type] + return new_ser.__finalize__(self) def _get_values(self, indexer: slice | npt.NDArray[np.bool_]) -> Series: new_mgr = self._mgr.getitem_mgr(indexer)