Skip to content

Commit 7cc1791

Browse files
Backport PR #51571 on branch 2.0.x (ENH: DataFrame.fillna making deep copy for dict arg) (#51636)
Backport PR #51571: ENH: DataFrame.fillna making deep copy for dict arg Co-authored-by: Patrick Hoefler <[email protected]>
1 parent 2bd5f28 commit 7cc1791

File tree

3 files changed

+35
-4
lines changed

3 files changed

+35
-4
lines changed

pandas/core/generic.py

+8-4
Original file line numberDiff line numberDiff line change
@@ -6876,8 +6876,10 @@ def fillna(
68766876
"with dict/Series column "
68776877
"by column"
68786878
)
6879-
6880-
result = self if inplace else self.copy()
6879+
if using_copy_on_write():
6880+
result = self.copy(deep=None)
6881+
else:
6882+
result = self if inplace else self.copy()
68816883
is_dict = isinstance(downcast, dict)
68826884
for k, v in value.items():
68836885
if k not in result:
@@ -6931,8 +6933,10 @@ def fillna(
69316933
result.iloc[:, loc] = res_loc
69326934
else:
69336935
result.isetitem(loc, res_loc)
6934-
6935-
return result if not inplace else None
6936+
if inplace:
6937+
return self._update_inplace(result)
6938+
else:
6939+
return result
69366940

69376941
elif not is_list_like(value):
69386942
if axis == 1:

pandas/tests/copy_view/test_interp_fillna.py

+15
Original file line numberDiff line numberDiff line change
@@ -180,6 +180,21 @@ def test_fillna(using_copy_on_write):
180180
tm.assert_frame_equal(df_orig, df)
181181

182182

183+
def test_fillna_dict(using_copy_on_write):
184+
df = DataFrame({"a": [1.5, np.nan], "b": 1})
185+
df_orig = df.copy()
186+
187+
df2 = df.fillna({"a": 100.5})
188+
if using_copy_on_write:
189+
assert np.shares_memory(get_array(df, "b"), get_array(df2, "b"))
190+
assert not np.shares_memory(get_array(df, "a"), get_array(df2, "a"))
191+
else:
192+
assert not np.shares_memory(get_array(df, "b"), get_array(df2, "b"))
193+
194+
df2.iloc[0, 1] = 100
195+
tm.assert_frame_equal(df_orig, df)
196+
197+
183198
@pytest.mark.parametrize("downcast", [None, False])
184199
def test_fillna_inplace(using_copy_on_write, downcast):
185200
df = DataFrame({"a": [1.5, np.nan], "b": 1})

pandas/tests/extension/json/test_json.py

+12
Original file line numberDiff line numberDiff line change
@@ -301,6 +301,18 @@ def test_searchsorted(self, data_for_sorting):
301301
def test_equals(self, data, na_value, as_series):
302302
super().test_equals(data, na_value, as_series)
303303

304+
def test_fillna_copy_frame(self, data_missing, using_copy_on_write):
305+
arr = data_missing.take([1, 1])
306+
df = pd.DataFrame({"A": arr})
307+
308+
filled_val = df.iloc[0, 0]
309+
result = df.fillna(filled_val)
310+
311+
if using_copy_on_write:
312+
assert df.A.values is result.A.values
313+
else:
314+
assert df.A.values is not result.A.values
315+
304316

305317
class TestCasting(BaseJSON, base.BaseCastingTests):
306318
@pytest.mark.xfail(reason="failing on np.array(self, dtype=str)")

0 commit comments

Comments
 (0)