Skip to content

Commit fcf7811

Browse files
authored
CoW: Add ChainedAssignmentError for replace with inplace=True (#54023)
1 parent aa4922a commit fcf7811

File tree

4 files changed

+25
-1
lines changed

4 files changed

+25
-1
lines changed

doc/source/whatsnew/v2.1.0.rst

+1
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,7 @@ Copy-on-Write improvements
7575

7676
- DataFrame.update / Series.update
7777
- DataFrame.fillna / Series.fillna
78+
- DataFrame.replace / Series.replace
7879

7980
.. _whatsnew_210.enhancements.enhancement2:
8081

pandas/core/generic.py

+9
Original file line numberDiff line numberDiff line change
@@ -7631,6 +7631,15 @@ def replace(
76317631
)
76327632

76337633
inplace = validate_bool_kwarg(inplace, "inplace")
7634+
if inplace:
7635+
if not PYPY and using_copy_on_write():
7636+
if sys.getrefcount(self) <= REF_COUNT:
7637+
warnings.warn(
7638+
_chained_assignment_method_msg,
7639+
ChainedAssignmentError,
7640+
stacklevel=2,
7641+
)
7642+
76347643
if not is_bool(regex) and to_replace is not None:
76357644
raise ValueError("'to_replace' must be 'None' if 'regex' is not a bool")
76367645

pandas/tests/arrays/categorical/test_replace.py

+2-1
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,8 @@ def test_replace_categorical(to_replace, value, result, expected_error_msg):
6868
# ensure non-inplace call does not affect original
6969
tm.assert_categorical_equal(cat, expected)
7070

71-
pd.Series(cat, copy=False).replace(to_replace, value, inplace=True)
71+
ser = pd.Series(cat, copy=False)
72+
ser.replace(to_replace, value, inplace=True)
7273
tm.assert_categorical_equal(cat, expected)
7374

7475

pandas/tests/copy_view/test_replace.py

+13
Original file line numberDiff line numberDiff line change
@@ -373,3 +373,16 @@ def test_replace_columnwise_no_op(using_copy_on_write):
373373
assert not np.shares_memory(get_array(df2, "a"), get_array(df, "a"))
374374
df2.iloc[0, 0] = 100
375375
tm.assert_frame_equal(df, df_orig)
376+
377+
378+
def test_replace_chained_assignment(using_copy_on_write):
379+
df = DataFrame({"a": [1, np.nan, 2], "b": 1})
380+
df_orig = df.copy()
381+
if using_copy_on_write:
382+
with tm.raises_chained_assignment_error():
383+
df["a"].replace(1, 100, inplace=True)
384+
tm.assert_frame_equal(df, df_orig)
385+
386+
with tm.raises_chained_assignment_error():
387+
df[["a"]].replace(1, 100, inplace=True)
388+
tm.assert_frame_equal(df, df_orig)

0 commit comments

Comments
 (0)