Skip to content

Commit 0270b23

Browse files
authored
BUG: loc.setitem raising ValueError when df has duplicate columns (#39278)
1 parent fe0fcd6 commit 0270b23

File tree

3 files changed

+14
-3
lines changed

3 files changed

+14
-3
lines changed

doc/source/whatsnew/v1.3.0.rst

+1
Original file line numberDiff line numberDiff line change
@@ -282,6 +282,7 @@ Indexing
282282
- 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`)
283283
- 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`)
284284
- 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`)
285+
- Bug in :meth:`DataFrame.loc.__setitem__` raising ValueError when expanding unique column for :class:`DataFrame` with duplicate columns (:issue:`38521`)
285286
- Bug in :meth:`DataFrame.iloc.__setitem__` and :meth:`DataFrame.loc.__setitem__` with mixed dtypes when setting with a dictionary value (:issue:`38335`)
286287
- Bug in :meth:`DataFrame.loc` dropping levels of :class:`MultiIndex` when :class:`DataFrame` used as input has only one row (:issue:`10521`)
287288
- Bug in setting ``timedelta64`` values into numeric :class:`Series` failing to cast to object dtype (:issue:`39086`)

pandas/core/indexing.py

+4-3
Original file line numberDiff line numberDiff line change
@@ -1842,10 +1842,11 @@ def _setitem_single_block(self, indexer, value, name: str):
18421842
for i, idx in enumerate(indexer)
18431843
if i != info_axis
18441844
)
1845-
and item_labels.is_unique
18461845
):
1847-
self.obj[item_labels[indexer[info_axis]]] = value
1848-
return
1846+
selected_item_labels = item_labels[indexer[info_axis]]
1847+
if len(item_labels.get_indexer_for([selected_item_labels])) == 1:
1848+
self.obj[selected_item_labels] = value
1849+
return
18491850

18501851
indexer = maybe_convert_ix(*indexer)
18511852
if (isinstance(value, ABCSeries) and name != "iloc") or isinstance(value, dict):

pandas/tests/frame/indexing/test_setitem.py

+9
Original file line numberDiff line numberDiff line change
@@ -373,6 +373,15 @@ def test_setitem_string_column_numpy_dtype_raising(self):
373373
expected = DataFrame([[1, 2, 5], [3, 4, 6]], columns=[0, 1, "0 - Name"])
374374
tm.assert_frame_equal(df, expected)
375375

376+
def test_setitem_empty_df_duplicate_columns(self):
377+
# GH#38521
378+
df = DataFrame(columns=["a", "b", "b"], dtype="float64")
379+
df.loc[:, "a"] = list(range(2))
380+
expected = DataFrame(
381+
[[0, np.nan, np.nan], [1, np.nan, np.nan]], columns=["a", "b", "b"]
382+
)
383+
tm.assert_frame_equal(df, expected)
384+
376385

377386
class TestDataFrameSetItemSlicing:
378387
def test_setitem_slice_position(self):

0 commit comments

Comments
 (0)