Skip to content

Commit 62c7dd3

Browse files
authored
Fix MultiIndex melt when col_level is used (#34329)
1 parent 1de24c9 commit 62c7dd3

File tree

3 files changed

+41
-10
lines changed

3 files changed

+41
-10
lines changed

doc/source/whatsnew/v1.1.0.rst

+1
Original file line numberDiff line numberDiff line change
@@ -885,6 +885,7 @@ Reshaping
885885
- Bug in :func:`cut` raised an error when non-unique labels (:issue:`33141`)
886886
- Bug in :meth:`DataFrame.replace` casts columns to ``object`` dtype if items in ``to_replace`` not in values (:issue:`32988`)
887887
- Ensure only named functions can be used in :func:`eval()` (:issue:`32460`)
888+
- Fixed bug in :func:`melt` where melting MultiIndex columns with ``col_level`` > 0 would raise a ``KeyError`` on ``id_vars`` (:issue:`34129`)
888889

889890
Sparse
890891
^^^^^^

pandas/core/reshape/melt.py

+7-1
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,13 @@ def melt(
7272
"The following 'value_vars' are not present in "
7373
f"the DataFrame: {list(missing)}"
7474
)
75-
frame = frame.loc[:, id_vars + value_vars]
75+
if col_level is not None:
76+
idx = frame.columns.get_level_values(col_level).get_indexer(
77+
id_vars + value_vars
78+
)
79+
else:
80+
idx = frame.columns.get_indexer(id_vars + value_vars)
81+
frame = frame.iloc[:, idx]
7682
else:
7783
frame = frame.copy()
7884

pandas/tests/reshape/test_melt.py

+33-9
Original file line numberDiff line numberDiff line change
@@ -100,15 +100,39 @@ def test_vars_work_with_multiindex(self):
100100
result = self.df1.melt(id_vars=[("A", "a")], value_vars=[("B", "b")])
101101
tm.assert_frame_equal(result, expected)
102102

103-
def test_single_vars_work_with_multiindex(self):
104-
expected = DataFrame(
105-
{
106-
"A": {0: 1.067683, 1: -1.321405, 2: -0.807333},
107-
"CAP": {0: "B", 1: "B", 2: "B"},
108-
"value": {0: -1.110463, 1: 0.368915, 2: 0.08298},
109-
}
110-
)
111-
result = self.df1.melt(["A"], ["B"], col_level=0)
103+
@pytest.mark.parametrize(
104+
"id_vars, value_vars, col_level, expected",
105+
[
106+
(
107+
["A"],
108+
["B"],
109+
0,
110+
DataFrame(
111+
{
112+
"A": {0: 1.067683, 1: -1.321405, 2: -0.807333},
113+
"CAP": {0: "B", 1: "B", 2: "B"},
114+
"value": {0: -1.110463, 1: 0.368915, 2: 0.08298},
115+
}
116+
),
117+
),
118+
(
119+
["a"],
120+
["b"],
121+
1,
122+
DataFrame(
123+
{
124+
"a": {0: 1.067683, 1: -1.321405, 2: -0.807333},
125+
"low": {0: "b", 1: "b", 2: "b"},
126+
"value": {0: -1.110463, 1: 0.368915, 2: 0.08298},
127+
}
128+
),
129+
),
130+
],
131+
)
132+
def test_single_vars_work_with_multiindex(
133+
self, id_vars, value_vars, col_level, expected
134+
):
135+
result = self.df1.melt(id_vars, value_vars, col_level=col_level)
112136
tm.assert_frame_equal(result, expected)
113137

114138
def test_tuple_vars_fail_with_multiindex(self):

0 commit comments

Comments
 (0)