From 4dfd328802805d2902193ea0684c4dc89800f013 Mon Sep 17 00:00:00 2001 From: phofl Date: Tue, 19 Jan 2021 22:18:57 +0100 Subject: [PATCH 1/2] BUG: DataFrame.__setitem__ raising ValueError when setting multiple values to dup columns --- doc/source/whatsnew/v1.3.0.rst | 1 + pandas/core/frame.py | 3 +++ pandas/tests/frame/indexing/test_setitem.py | 18 ++++++++++++++++++ 3 files changed, 22 insertions(+) diff --git a/doc/source/whatsnew/v1.3.0.rst b/doc/source/whatsnew/v1.3.0.rst index 5422134f220d7..776f3c184b88b 100644 --- a/doc/source/whatsnew/v1.3.0.rst +++ b/doc/source/whatsnew/v1.3.0.rst @@ -275,6 +275,7 @@ Indexing ^^^^^^^^ - Bug in :meth:`CategoricalIndex.get_indexer` failing to raise ``InvalidIndexError`` when non-unique (:issue:`38372`) - Bug in inserting many new columns into a :class:`DataFrame` causing incorrect subsequent indexing behavior (:issue:`38380`) +- Bug in :meth:`DataFrame.__setitem__` raising ``ValueError`` when setting multiple values to duplicate columns (:issue:`15695`) - Bug in :meth:`DataFrame.loc`, :meth:`Series.loc`, :meth:`DataFrame.__getitem__` and :meth:`Series.__getitem__` returning incorrect elements for non-monotonic :class:`DatetimeIndex` for string slices (:issue:`33146`) - Bug in :meth:`DataFrame.reindex` and :meth:`Series.reindex` with timezone aware indexes raising ``TypeError`` for ``method="ffill"`` and ``method="bfill"`` and specified ``tolerance`` (:issue:`38566`) - Bug in :meth:`DataFrame.__setitem__` raising ``ValueError`` with empty :class:`DataFrame` and specified columns for string indexer and non empty :class:`DataFrame` to set (:issue:`38831`) diff --git a/pandas/core/frame.py b/pandas/core/frame.py index ffc84ad94459a..c9ac5033d4431 100644 --- a/pandas/core/frame.py +++ b/pandas/core/frame.py @@ -3195,6 +3195,9 @@ def __setitem__(self, key, value): self._setitem_array(key, value) elif isinstance(value, DataFrame): self._set_item_frame_value(key, value) + elif len(self.columns.get_indexer_for([key])) > 1: + # Column to set is duplicated + self._setitem_array(key, value) else: # set column self._set_item(key, value) diff --git a/pandas/tests/frame/indexing/test_setitem.py b/pandas/tests/frame/indexing/test_setitem.py index 295c8a27e6ddd..dde09ba4bc86b 100644 --- a/pandas/tests/frame/indexing/test_setitem.py +++ b/pandas/tests/frame/indexing/test_setitem.py @@ -348,6 +348,24 @@ def test_setitem_frame_length_0_str_key(self, indexer): expected["A"] = expected["A"].astype("object") tm.assert_frame_equal(df, expected) + def test_setitem_frame_duplicate_columns(self): + # GH#15695 + cols = ["A", "B", "C"] * 2 + df = DataFrame(index=range(3), columns=cols) + df.loc[0, "A"] = (0, 3) + df.loc[:, "B"] = (1, 4) + df["C"] = (2, 5) + expected = DataFrame( + [ + [0, 1, 2, 3, 4, 5], + [np.nan, 1, 2, np.nan, 4, 5], + [np.nan, 1, 2, np.nan, 4, 5], + ], + columns=cols, + dtype="object", + ) + tm.assert_frame_equal(df, expected) + class TestDataFrameSetItemWithExpansion: def test_setitem_listlike_views(self): From 09a59e034c81c03e51f9a348d49c35d392210c3d Mon Sep 17 00:00:00 2001 From: phofl Date: Tue, 19 Jan 2021 23:30:35 +0100 Subject: [PATCH 2/2] Fix bug in condition --- pandas/core/frame.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/pandas/core/frame.py b/pandas/core/frame.py index c9ac5033d4431..eb75d76660c48 100644 --- a/pandas/core/frame.py +++ b/pandas/core/frame.py @@ -3195,9 +3195,11 @@ def __setitem__(self, key, value): self._setitem_array(key, value) elif isinstance(value, DataFrame): self._set_item_frame_value(key, value) - elif len(self.columns.get_indexer_for([key])) > 1: + elif is_list_like(value) and 1 < len( + self.columns.get_indexer_for([key]) + ) == len(value): # Column to set is duplicated - self._setitem_array(key, value) + self._setitem_array([key], value) else: # set column self._set_item(key, value)