融化一堆 multiIndexed 列,同时保留一个 'index' 列

Melt a bunch of multiIndexed columns while keeping a single 'index' column

我有一个很大的 table,其中的行代表观察结果。我的列的子集可以按两个元类别分组,因此我使用多索引来表示这些列。但是,多索引并不适用于所有列。因此所有剩余的列仅在第一级具有索引标签。

我想将 melt() 应用于其中一些多维列,然后通过索引列将它们与我的主 table 合并()回来。

这是我遇到的部分的 MRE。我有一个这样的数据框:

df = pd.DataFrame({
  ('INDEX',): [1,2,3],
  ('a','x'): ['ww','rt','pb'],
  ('a','y'): [88,97,12],
  ('b','x'): ['ew','tr','cv'],
  ('b','y'): [14,42,67],
  ('c','x'): ['wq','fg','dg'],
  ('c','y'): [65,78,46]})

df
  INDEX   a       b       c
    NaN   x   y   x   y   x   y
0     1  ww  88  ew  14  wq  65
1     2  rt  97  tr  42  fg  78
2     3  pb  12  cv  67  dg  46

现在我想要这个:

df.melt(id_vars=('INDEX',))

...结果是:

INDEX thing_1 thing_2 value
    1       a       x    ww
    2       a       x    rt
    3       a       x    pb
    1       a       y    88
    2       a       y    97
    3       a       y    12
    1       b       x    ew
    2       b       x    tr
    3       b       x    cv
    1       b       y    14
    2       b       y    42
    3       b       y    67
    1       c       x    wq
    2       c       x    fg
    3       c       x    dg
    1       c       y    65
    2       c       y    78
    3       c       y    46

但我得到一个以 Exception: Data must be 1-dimensional 结尾的长回溯。

当我第一次开始尝试这个时,我试图提供 value_vars 但没有成功;后来我意识到 del df['INDEX']; df.melt() 可以正常工作,当然我想保留我的 INDEX 列。

我也尝试了一些变体,例如将 'INDEX' 放入 1 元组、以 np.nanslice(None) 结尾的 2 元组、列表等。我得到关于一维数据的相同抱怨,或者在某些情况下,ValueError: id_vars must be a list of tuples when columns are a MultiIndex.

解决这个问题的正确方法是什么?经过多次试验和错误后,我找到了一个解决方案,我将在下面 post,但它似乎应该更简单或更优雅。谢谢。

在我开始写这个问题后,我偶然发现了一个解决方案。

如果我在我的 DataFrame 作业中将 ('INDEX',) 替换为 ('INDEX','foo'),那么我会得到我想要的解决方案,如下所示:

df.melt(id_vars=[('INDEX','foo')])

    (INDEX, foo) variable_0 variable_1 value
0              1          a          x    ww
1              2          a          x    rt
2              3          a          x    pb
3              1          a          y    88
4              2          a          y    97
[...]

您可以使用空字符串作为 INDEX

的第 2 层
df = pd.DataFrame({
  ('INDEX',''): [1,2,3],
  ('a','x'): ['ww','rt','pb'],
  ('a','y'): [88,97,12],
  ('b','x'): ['ew','tr','cv'],
  ('b','y'): [14,42,67],
  ('c','x'): ['wq','fg','dg'],
  ('c','y'): [65,78,46]})

In [198]: df
Out[198]:
  INDEX   a       b       c
          x   y   x   y   x   y
0     1  ww  88  ew  14  wq  65
1     2  rt  97  tr  42  fg  78
2     3  pb  12  cv  67  dg  46

df.melt(id_vars='INDEX')

Out[200]:
    INDEX variable_0 variable_1 value
0       1          a          x    ww
1       2          a          x    rt
2       3          a          x    pb
3       1          a          y    88
4       2          a          y    97
5       3          a          y    12
6       1          b          x    ew
7       2          b          x    tr
8       3          b          x    cv
9       1          b          y    14
10      2          b          y    42
11      3          b          y    67
12      1          c          x    wq
13      2          c          x    fg
14      3          c          x    dg
15      1          c          y    65
16      2          c          y    78
17      3          c          y    46