Skip to content

Commit

Permalink
Backport PR #51571 on branch 2.0.x (ENH: DataFrame.fillna making deep…
Browse files Browse the repository at this point in the history
… copy for dict arg) (#51636)

Backport PR #51571: ENH: DataFrame.fillna making deep copy for dict arg

Co-authored-by: Patrick Hoefler <61934744+phofl@users.noreply.github.com>
  • Loading branch information
meeseeksmachine and phofl committed Feb 25, 2023
1 parent 2bd5f28 commit 7cc1791
Show file tree
Hide file tree
Showing 3 changed files with 35 additions and 4 deletions.
12 changes: 8 additions & 4 deletions pandas/core/generic.py
Original file line number Diff line number Diff line change
Expand Up @@ -6876,8 +6876,10 @@ def fillna(
"with dict/Series column "
"by column"
)

result = self if inplace else self.copy()
if using_copy_on_write():
result = self.copy(deep=None)
else:
result = self if inplace else self.copy()
is_dict = isinstance(downcast, dict)
for k, v in value.items():
if k not in result:
Expand Down Expand Up @@ -6931,8 +6933,10 @@ def fillna(
result.iloc[:, loc] = res_loc
else:
result.isetitem(loc, res_loc)

return result if not inplace else None
if inplace:
return self._update_inplace(result)
else:
return result

elif not is_list_like(value):
if axis == 1:
Expand Down
15 changes: 15 additions & 0 deletions pandas/tests/copy_view/test_interp_fillna.py
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,21 @@ def test_fillna(using_copy_on_write):
tm.assert_frame_equal(df_orig, df)


def test_fillna_dict(using_copy_on_write):
df = DataFrame({"a": [1.5, np.nan], "b": 1})
df_orig = df.copy()

df2 = df.fillna({"a": 100.5})
if using_copy_on_write:
assert np.shares_memory(get_array(df, "b"), get_array(df2, "b"))
assert not np.shares_memory(get_array(df, "a"), get_array(df2, "a"))
else:
assert not np.shares_memory(get_array(df, "b"), get_array(df2, "b"))

df2.iloc[0, 1] = 100
tm.assert_frame_equal(df_orig, df)


@pytest.mark.parametrize("downcast", [None, False])
def test_fillna_inplace(using_copy_on_write, downcast):
df = DataFrame({"a": [1.5, np.nan], "b": 1})
Expand Down
12 changes: 12 additions & 0 deletions pandas/tests/extension/json/test_json.py
Original file line number Diff line number Diff line change
Expand Up @@ -301,6 +301,18 @@ def test_searchsorted(self, data_for_sorting):
def test_equals(self, data, na_value, as_series):
super().test_equals(data, na_value, as_series)

def test_fillna_copy_frame(self, data_missing, using_copy_on_write):
arr = data_missing.take([1, 1])
df = pd.DataFrame({"A": arr})

filled_val = df.iloc[0, 0]
result = df.fillna(filled_val)

if using_copy_on_write:
assert df.A.values is result.A.values
else:
assert df.A.values is not result.A.values


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

0 comments on commit 7cc1791

Please sign in to comment.