Skip to content

Commit 3364f9a

Browse files
authored
REGR: Fix fillna making a copy when dict was given as fill value and inplace is set (#47327)
1 parent f6eacb4 commit 3364f9a

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
@@ -18,6 +18,7 @@ Fixed regressions
1818
- Fixed regression in :meth:`DataFrame.to_csv` raising error when :class:`DataFrame` contains extension dtype categorical column (:issue:`46297`, :issue:`46812`)
1919
- Fixed regression in representation of ``dtypes`` attribute of :class:`MultiIndex` (:issue:`46900`)
2020
- 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`)
21+
- Fixed regression in :meth:`DataFrame.fillna` and :meth:`DataFrame.update` creating a copy when updating inplace (:issue:`47188`)
2122
- Fixed regression in :meth:`DataFrame.nsmallest` led to wrong results when ``np.nan`` in the sorting column (:issue:`46589`)
2223
- Fixed regression in :func:`read_fwf` raising ``ValueError`` when ``widths`` was specified with ``usecols`` (:issue:`46580`)
2324
- 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
@@ -8000,7 +8000,7 @@ def update(
80008000
if mask.all():
80018001
continue
80028002

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

80058005
# ----------------------------------------------------------------------
80068006
# Data reshaping

pandas/core/generic.py

+3-1
Original file line numberDiff line numberDiff line change
@@ -6522,7 +6522,9 @@ def fillna(
65226522
if k not in result:
65236523
continue
65246524
downcast_k = downcast if not is_dict else downcast.get(k)
6525-
result[k] = result[k].fillna(v, limit=limit, downcast=downcast_k)
6525+
result.loc[:, k] = result[k].fillna(
6526+
v, limit=limit, downcast=downcast_k
6527+
)
65266528
return result if not inplace else None
65276529

65286530
elif not is_list_like(value):

pandas/tests/frame/methods/test_fillna.py

+12
Original file line numberDiff line numberDiff line change
@@ -284,6 +284,7 @@ def test_fillna_downcast_noop(self, frame_or_series):
284284
res3 = obj2.fillna("foo", downcast=np.dtype(np.int32))
285285
tm.assert_equal(res3, expected)
286286

287+
@td.skip_array_manager_not_yet_implemented
287288
@pytest.mark.parametrize("columns", [["A", "A", "B"], ["A", "A"]])
288289
def test_fillna_dictlike_value_duplicate_colnames(self, columns):
289290
# GH#43476
@@ -673,6 +674,17 @@ def test_fillna_inplace_with_columns_limit_and_value(self):
673674
df.fillna(axis=1, value=100, limit=1, inplace=True)
674675
tm.assert_frame_equal(df, expected)
675676

677+
@td.skip_array_manager_invalid_test
678+
@pytest.mark.parametrize("val", [-1, {"x": -1, "y": -1}])
679+
def test_inplace_dict_update_view(self, val):
680+
# GH#47188
681+
df = DataFrame({"x": [np.nan, 2], "y": [np.nan, 2]})
682+
result_view = df[:]
683+
df.fillna(val, inplace=True)
684+
expected = DataFrame({"x": [-1, 2.0], "y": [-1.0, 2]})
685+
tm.assert_frame_equal(df, expected)
686+
tm.assert_frame_equal(result_view, expected)
687+
676688

677689
def test_fillna_nonconsolidated_frame():
678690
# 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)