From a2a1a9101ac2fa8faa2b11db858bfcf20924af7b Mon Sep 17 00:00:00 2001 From: Joris Van den Bossche Date: Sun, 15 Sep 2024 22:00:26 +0200 Subject: [PATCH 1/2] BUG (CoW): fix reference tracking in replace_list with None (#59807) (cherry picked from commit 3e8ac12d1dacc2308b2f4c2869fa7bc2079bd323) --- pandas/core/internals/blocks.py | 2 +- pandas/tests/copy_view/test_replace.py | 6 ++++++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/pandas/core/internals/blocks.py b/pandas/core/internals/blocks.py index 259e969112dd7..2f448bf249a2e 100644 --- a/pandas/core/internals/blocks.py +++ b/pandas/core/internals/blocks.py @@ -1218,7 +1218,7 @@ def _replace_coerce( putmask_inplace(nb.values, mask, value) return [nb] if using_cow: - return [self] + return [self.copy(deep=False)] return [self] if inplace else [self.copy()] return self.replace( to_replace=to_replace, diff --git a/pandas/tests/copy_view/test_replace.py b/pandas/tests/copy_view/test_replace.py index 6d16bc3083883..9266f8905d656 100644 --- a/pandas/tests/copy_view/test_replace.py +++ b/pandas/tests/copy_view/test_replace.py @@ -384,6 +384,12 @@ def test_replace_list_none(using_copy_on_write): assert not np.shares_memory(get_array(df, "a"), get_array(df2, "a")) + # replace multiple values that don't actually replace anything with None + # https://github.com/pandas-dev/pandas/issues/59770 + df3 = df.replace(["d", "e", "f"], value=None) + tm.assert_frame_equal(df3, df_orig) + assert tm.shares_memory(get_array(df, "a"), get_array(df3, "a")) + def test_replace_list_none_inplace_refs(using_copy_on_write, warn_copy_on_write): df = DataFrame({"a": ["a", "b", "c"]}) From b002e38d33a1bdc866779d7bfe93ff5bffd51a20 Mon Sep 17 00:00:00 2001 From: Joris Van den Bossche Date: Wed, 2 Oct 2024 22:04:28 +0200 Subject: [PATCH 2/2] correct test to work without CoW --- pandas/tests/copy_view/test_replace.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/pandas/tests/copy_view/test_replace.py b/pandas/tests/copy_view/test_replace.py index 9266f8905d656..0beac439fbb58 100644 --- a/pandas/tests/copy_view/test_replace.py +++ b/pandas/tests/copy_view/test_replace.py @@ -388,7 +388,10 @@ def test_replace_list_none(using_copy_on_write): # https://github.com/pandas-dev/pandas/issues/59770 df3 = df.replace(["d", "e", "f"], value=None) tm.assert_frame_equal(df3, df_orig) - assert tm.shares_memory(get_array(df, "a"), get_array(df3, "a")) + if using_copy_on_write: + assert tm.shares_memory(get_array(df, "a"), get_array(df3, "a")) + else: + assert not tm.shares_memory(get_array(df, "a"), get_array(df3, "a")) def test_replace_list_none_inplace_refs(using_copy_on_write, warn_copy_on_write):