From c92c9536710d0e7c980112cf971eeed19198b9bd Mon Sep 17 00:00:00 2001 From: Simon Hawkins Date: Tue, 23 Aug 2022 14:54:47 +0100 Subject: [PATCH] Backport PR #47774 on branch 1.4.x (BUG: Fix fillna on multi indexed Dataframe doesn't work) (#48216) Backport PR #47774: BUG: Fix fillna on multi indexed Dataframe doesn't work Co-authored-by: Xingrong Chen <56777910+xr-chen@users.noreply.github.com> --- doc/source/whatsnew/v1.4.4.rst | 1 + pandas/core/generic.py | 9 ++++++-- pandas/tests/frame/methods/test_fillna.py | 28 +++++++++++++++++++++++ 3 files changed, 36 insertions(+), 2 deletions(-) diff --git a/doc/source/whatsnew/v1.4.4.rst b/doc/source/whatsnew/v1.4.4.rst index dbdeebad06af0..3d0a6e01826f8 100644 --- a/doc/source/whatsnew/v1.4.4.rst +++ b/doc/source/whatsnew/v1.4.4.rst @@ -14,6 +14,7 @@ including other versions of pandas. Fixed regressions ~~~~~~~~~~~~~~~~~ +- Fixed regression in :meth:`DataFrame.fillna` not working :class:`DataFrame` with :class:`MultiIndex` (:issue:`47649`) - Fixed regression in taking NULL :class:`objects` from a :class:`DataFrame` causing a segmentation violation. These NULL values are created by :meth:`numpy.empty_like` (:issue:`46848`) - Fixed regression in :func:`concat` materializing :class:`Index` during sorting even if :class:`Index` was already sorted (:issue:`47501`) - Fixed regression in calling bitwise numpy ufuncs (for example, ``np.bitwise_and``) on Index objects (:issue:`46769`) diff --git a/pandas/core/generic.py b/pandas/core/generic.py index c5bdddd9f9aa7..ba63d08d7c1a9 100644 --- a/pandas/core/generic.py +++ b/pandas/core/generic.py @@ -6482,9 +6482,14 @@ def fillna( if k not in result: continue downcast_k = downcast if not is_dict else downcast.get(k) - result.loc[:, k] = result[k].fillna( - v, limit=limit, downcast=downcast_k + # GH47649 + result.loc[:, k] = ( + result[k].fillna(v, limit=limit, downcast=downcast_k).values ) + # TODO: result.loc[:, k] = result.loc[:, k].fillna( + # v, limit=limit, downcast=downcast_k + # ) + # Revert when GH45751 is fixed return result if not inplace else None elif not is_list_like(value): diff --git a/pandas/tests/frame/methods/test_fillna.py b/pandas/tests/frame/methods/test_fillna.py index 33bd32ad65371..ffb36166296af 100644 --- a/pandas/tests/frame/methods/test_fillna.py +++ b/pandas/tests/frame/methods/test_fillna.py @@ -666,6 +666,34 @@ def test_inplace_dict_update_view(self, val): tm.assert_frame_equal(df, expected) tm.assert_frame_equal(result_view, expected) + def test_fillna_with_multi_index_frame(self): + # GH 47649 + pdf = DataFrame( + { + ("x", "a"): [np.nan, 2.0, 3.0], + ("x", "b"): [1.0, 2.0, np.nan], + ("y", "c"): [1.0, 2.0, np.nan], + } + ) + expected = DataFrame( + { + ("x", "a"): [-1.0, 2.0, 3.0], + ("x", "b"): [1.0, 2.0, -1.0], + ("y", "c"): [1.0, 2.0, np.nan], + } + ) + tm.assert_frame_equal(pdf.fillna({"x": -1}), expected) + tm.assert_frame_equal(pdf.fillna({"x": -1, ("x", "b"): -2}), expected) + + expected = DataFrame( + { + ("x", "a"): [-1.0, 2.0, 3.0], + ("x", "b"): [1.0, 2.0, -2.0], + ("y", "c"): [1.0, 2.0, np.nan], + } + ) + tm.assert_frame_equal(pdf.fillna({("x", "b"): -2, "x": -1}), expected) + def test_fillna_nonconsolidated_frame(): # https://github.com/pandas-dev/pandas/issues/36495