Skip to content

Commit 8f846ae

Browse files
Backport PR #47327 on branch 1.4.x (REGR: Fix fillna making a copy when dict was given as fill value and inplace is set) (#47448)
* Backport PR #47327: REGR: Fix fillna making a copy when dict was given as fill value and inplace is set Co-authored-by: Patrick Hoefler <[email protected]>
1 parent ad7dc56 commit 8f846ae

File tree

5 files changed

+30
-2
lines changed

5 files changed

+30
-2
lines changed

doc/source/whatsnew/v1.4.3.rst

+1
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ Fixed regressions
2929
- Fixed regression in :meth:`DataFrame.to_csv` raising error when :class:`DataFrame` contains extension dtype categorical column (:issue:`46297`, :issue:`46812`)
3030
- Fixed regression in representation of ``dtypes`` attribute of :class:`MultiIndex` (:issue:`46900`)
3131
- Fixed regression when setting values with :meth:`DataFrame.loc` updating :class:`RangeIndex` when index was set as new column and column was updated afterwards (:issue:`47128`)
32+
- Fixed regression in :meth:`DataFrame.fillna` and :meth:`DataFrame.update` creating a copy when updating inplace (:issue:`47188`)
3233
- Fixed regression in :meth:`DataFrame.nsmallest` led to wrong results when ``np.nan`` in the sorting column (:issue:`46589`)
3334
- Fixed regression in :func:`read_fwf` raising ``ValueError`` when ``widths`` was specified with ``usecols`` (:issue:`46580`)
3435
- Fixed regression in :func:`concat` not sorting columns for mixed column names (:issue:`47127`)

pandas/core/frame.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -7594,7 +7594,7 @@ def update(
75947594
if mask.all():
75957595
continue
75967596

7597-
self[col] = expressions.where(mask, this, that)
7597+
self.loc[:, col] = expressions.where(mask, this, that)
75987598

75997599
# ----------------------------------------------------------------------
76007600
# Data reshaping

pandas/core/generic.py

+3-1
Original file line numberDiff line numberDiff line change
@@ -6482,7 +6482,9 @@ def fillna(
64826482
if k not in result:
64836483
continue
64846484
downcast_k = downcast if not is_dict else downcast.get(k)
6485-
result[k] = result[k].fillna(v, limit=limit, downcast=downcast_k)
6485+
result.loc[:, k] = result[k].fillna(
6486+
v, limit=limit, downcast=downcast_k
6487+
)
64866488
return result if not inplace else None
64876489

64886490
elif not is_list_like(value):

pandas/tests/frame/methods/test_fillna.py

+12
Original file line numberDiff line numberDiff line change
@@ -265,6 +265,7 @@ def test_fillna_downcast_false(self, frame_or_series):
265265
result = obj.fillna("", downcast=False)
266266
tm.assert_equal(result, obj)
267267

268+
@td.skip_array_manager_invalid_test
268269
@pytest.mark.parametrize("columns", [["A", "A", "B"], ["A", "A"]])
269270
def test_fillna_dictlike_value_duplicate_colnames(self, columns):
270271
# GH#43476
@@ -654,6 +655,17 @@ def test_fillna_inplace_with_columns_limit_and_value(self):
654655
df.fillna(axis=1, value=100, limit=1, inplace=True)
655656
tm.assert_frame_equal(df, expected)
656657

658+
@td.skip_array_manager_invalid_test
659+
@pytest.mark.parametrize("val", [-1, {"x": -1, "y": -1}])
660+
def test_inplace_dict_update_view(self, val):
661+
# GH#47188
662+
df = DataFrame({"x": [np.nan, 2], "y": [np.nan, 2]})
663+
result_view = df[:]
664+
df.fillna(val, inplace=True)
665+
expected = DataFrame({"x": [-1, 2.0], "y": [-1.0, 2]})
666+
tm.assert_frame_equal(df, expected)
667+
tm.assert_frame_equal(result_view, expected)
668+
657669

658670
def test_fillna_nonconsolidated_frame():
659671
# https://github.com/pandas-dev/pandas/issues/36495

pandas/tests/frame/methods/test_update.py

+13
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
import numpy as np
22
import pytest
33

4+
import pandas.util._test_decorators as td
5+
46
import pandas as pd
57
from pandas import (
68
DataFrame,
@@ -146,3 +148,14 @@ def test_update_with_different_dtype(self):
146148

147149
expected = DataFrame({"a": [1, 3], "b": [np.nan, 2], "c": ["foo", np.nan]})
148150
tm.assert_frame_equal(df, expected)
151+
152+
@td.skip_array_manager_invalid_test
153+
def test_update_modify_view(self):
154+
# GH#47188
155+
df = DataFrame({"A": ["1", np.nan], "B": ["100", np.nan]})
156+
df2 = DataFrame({"A": ["a", "x"], "B": ["100", "200"]})
157+
result_view = df2[:]
158+
df2.update(df)
159+
expected = DataFrame({"A": ["1", "x"], "B": ["100", "200"]})
160+
tm.assert_frame_equal(df2, expected)
161+
tm.assert_frame_equal(result_view, expected)

0 commit comments

Comments
 (0)