Skip to content

Commit

Permalink
Backport PR #47327 on branch 1.4.x (REGR: Fix fillna making a copy wh…
Browse files Browse the repository at this point in the history
…en 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 <61934744+phofl@users.noreply.github.com>
  • Loading branch information
simonjayhawkins and phofl authored Jun 22, 2022
1 parent ad7dc56 commit 8f846ae
Show file tree
Hide file tree
Showing 5 changed files with 30 additions and 2 deletions.
1 change: 1 addition & 0 deletions doc/source/whatsnew/v1.4.3.rst
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ Fixed regressions
- Fixed regression in :meth:`DataFrame.to_csv` raising error when :class:`DataFrame` contains extension dtype categorical column (:issue:`46297`, :issue:`46812`)
- Fixed regression in representation of ``dtypes`` attribute of :class:`MultiIndex` (:issue:`46900`)
- 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`)
- Fixed regression in :meth:`DataFrame.fillna` and :meth:`DataFrame.update` creating a copy when updating inplace (:issue:`47188`)
- Fixed regression in :meth:`DataFrame.nsmallest` led to wrong results when ``np.nan`` in the sorting column (:issue:`46589`)
- Fixed regression in :func:`read_fwf` raising ``ValueError`` when ``widths`` was specified with ``usecols`` (:issue:`46580`)
- Fixed regression in :func:`concat` not sorting columns for mixed column names (:issue:`47127`)
Expand Down
2 changes: 1 addition & 1 deletion pandas/core/frame.py
Original file line number Diff line number Diff line change
Expand Up @@ -7594,7 +7594,7 @@ def update(
if mask.all():
continue

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

# ----------------------------------------------------------------------
# Data reshaping
Expand Down
4 changes: 3 additions & 1 deletion pandas/core/generic.py
Original file line number Diff line number Diff line change
Expand Up @@ -6482,7 +6482,9 @@ def fillna(
if k not in result:
continue
downcast_k = downcast if not is_dict else downcast.get(k)
result[k] = result[k].fillna(v, limit=limit, downcast=downcast_k)
result.loc[:, k] = result[k].fillna(
v, limit=limit, downcast=downcast_k
)
return result if not inplace else None

elif not is_list_like(value):
Expand Down
12 changes: 12 additions & 0 deletions pandas/tests/frame/methods/test_fillna.py
Original file line number Diff line number Diff line change
Expand Up @@ -265,6 +265,7 @@ def test_fillna_downcast_false(self, frame_or_series):
result = obj.fillna("", downcast=False)
tm.assert_equal(result, obj)

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

@td.skip_array_manager_invalid_test
@pytest.mark.parametrize("val", [-1, {"x": -1, "y": -1}])
def test_inplace_dict_update_view(self, val):
# GH#47188
df = DataFrame({"x": [np.nan, 2], "y": [np.nan, 2]})
result_view = df[:]
df.fillna(val, inplace=True)
expected = DataFrame({"x": [-1, 2.0], "y": [-1.0, 2]})
tm.assert_frame_equal(df, expected)
tm.assert_frame_equal(result_view, expected)


def test_fillna_nonconsolidated_frame():
# https://github.com/pandas-dev/pandas/issues/36495
Expand Down
13 changes: 13 additions & 0 deletions pandas/tests/frame/methods/test_update.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import numpy as np
import pytest

import pandas.util._test_decorators as td

import pandas as pd
from pandas import (
DataFrame,
Expand Down Expand Up @@ -146,3 +148,14 @@ def test_update_with_different_dtype(self):

expected = DataFrame({"a": [1, 3], "b": [np.nan, 2], "c": ["foo", np.nan]})
tm.assert_frame_equal(df, expected)

@td.skip_array_manager_invalid_test
def test_update_modify_view(self):
# GH#47188
df = DataFrame({"A": ["1", np.nan], "B": ["100", np.nan]})
df2 = DataFrame({"A": ["a", "x"], "B": ["100", "200"]})
result_view = df2[:]
df2.update(df)
expected = DataFrame({"A": ["1", "x"], "B": ["100", "200"]})
tm.assert_frame_equal(df2, expected)
tm.assert_frame_equal(result_view, expected)

0 comments on commit 8f846ae

Please sign in to comment.