From 524f2a4214755014cce552126ea1340167ef5333 Mon Sep 17 00:00:00 2001 From: Matthew Zeitlin Date: Fri, 10 Sep 2021 00:40:32 -0400 Subject: [PATCH 1/2] BUG: fillna not replacing missing values when duplicate colnames --- doc/source/whatsnew/v1.4.0.rst | 1 + pandas/core/generic.py | 2 +- pandas/tests/frame/methods/test_fillna.py | 11 +++++++++++ 3 files changed, 13 insertions(+), 1 deletion(-) diff --git a/doc/source/whatsnew/v1.4.0.rst b/doc/source/whatsnew/v1.4.0.rst index 487ef5c226f94..294648d0fb291 100644 --- a/doc/source/whatsnew/v1.4.0.rst +++ b/doc/source/whatsnew/v1.4.0.rst @@ -369,6 +369,7 @@ Indexing Missing ^^^^^^^ - Bug in :meth:`DataFrame.fillna` with limit and no method ignores axis='columns' or ``axis = 1`` (:issue:`40989`) +- Bug in :meth:`DataFrame.fillna` not replacing missing values when using a dict-like ``value`` and duplicate column names (:issue:`43476`) - MultiIndex diff --git a/pandas/core/generic.py b/pandas/core/generic.py index 48daf7c89fe64..73d9e9e939533 100644 --- a/pandas/core/generic.py +++ b/pandas/core/generic.py @@ -6341,7 +6341,7 @@ def fillna( continue obj = result[k] downcast_k = downcast if not is_dict else downcast.get(k) - obj.fillna(v, limit=limit, inplace=True, downcast=downcast_k) + result[k] = obj.fillna(v, limit=limit, downcast=downcast_k) 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 56b0029b49779..7e486f9fac083 100644 --- a/pandas/tests/frame/methods/test_fillna.py +++ b/pandas/tests/frame/methods/test_fillna.py @@ -247,6 +247,17 @@ def test_fillna_downcast(self): expected = DataFrame({"a": [1, 0]}) tm.assert_frame_equal(result, expected) + @pytest.mark.parametrize("columns", [["A", "A", "B"], ["A", "A"]]) + def test_fillna_dictlike_value_duplicate_colnames(self, columns): + # GH#43476 + df = DataFrame(np.nan, index=[0, 1], columns=columns) + with tm.assert_produces_warning(None): + result = df.fillna({"A": 0}) + + expected = df.copy() + expected["A"] = 0.0 + tm.assert_frame_equal(result, expected) + @td.skip_array_manager_not_yet_implemented # TODO(ArrayManager) object upcasting def test_fillna_dtype_conversion(self): # make sure that fillna on an empty frame works From bb47bd1dcf3f233415697693b65419c8cf5b4917 Mon Sep 17 00:00:00 2001 From: Matthew Zeitlin Date: Fri, 10 Sep 2021 08:59:52 -0400 Subject: [PATCH 2/2] No need for obj --- pandas/core/generic.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/pandas/core/generic.py b/pandas/core/generic.py index 73d9e9e939533..b8485864704dd 100644 --- a/pandas/core/generic.py +++ b/pandas/core/generic.py @@ -6339,9 +6339,8 @@ def fillna( for k, v in value.items(): if k not in result: continue - obj = result[k] downcast_k = downcast if not is_dict else downcast.get(k) - result[k] = obj.fillna(v, limit=limit, downcast=downcast_k) + result[k] = result[k].fillna(v, limit=limit, downcast=downcast_k) return result if not inplace else None elif not is_list_like(value):