diff --git a/doc/source/whatsnew/v3.0.0.rst b/doc/source/whatsnew/v3.0.0.rst index 099e5bc48353a..5254b0de83b5a 100644 --- a/doc/source/whatsnew/v3.0.0.rst +++ b/doc/source/whatsnew/v3.0.0.rst @@ -847,6 +847,7 @@ Reshaping - Bug in :meth:`DataFrame.stack` with the new implementation where ``ValueError`` is raised when ``level=[]`` (:issue:`60740`) - Bug in :meth:`DataFrame.unstack` producing incorrect results when manipulating empty :class:`DataFrame` with an :class:`ExtentionDtype` (:issue:`59123`) - Bug in :meth:`concat` where concatenating DataFrame and Series with ``ignore_index = True`` drops the series name (:issue:`60723`, :issue:`56257`) +- Bug in :func:`melt` where calling with duplicate column names in ``id_vars`` raised a misleading ``AttributeError`` (:issue:`61475`) Sparse ^^^^^^ diff --git a/pandas/core/reshape/melt.py b/pandas/core/reshape/melt.py index f4cb82816bbcf..2683c407d404d 100644 --- a/pandas/core/reshape/melt.py +++ b/pandas/core/reshape/melt.py @@ -239,6 +239,9 @@ def melt( mdata: dict[Hashable, AnyArrayLike] = {} for col in id_vars: id_data = frame.pop(col) + # GH61475 - prevent AttributeError when duplicate column + if not hasattr(id_data, "dtype"): + raise Exception(f"{col} is a duplicate column header") if not isinstance(id_data.dtype, np.dtype): # i.e. ExtensionDtype if num_cols_adjusted > 0: diff --git a/pandas/tests/reshape/test_melt.py b/pandas/tests/reshape/test_melt.py index 95aa5291cb45a..3d49394352c8a 100644 --- a/pandas/tests/reshape/test_melt.py +++ b/pandas/tests/reshape/test_melt.py @@ -555,6 +555,14 @@ def test_melt_multiindex_columns_var_name_too_many(self): ): df.melt(var_name=["first", "second", "third"]) + def test_melt_duplicate_column_header_raises(self): + # GH61475 + df = DataFrame([[1, 2, 3], [3, 4, 5]], columns=["A", "A", "B"]) + msg = "A is a duplicate column header" + + with pytest.raises(Exception, match=msg): + df.melt(id_vars=["A"], value_vars=["B"]) + class TestLreshape: def test_pairs(self):