Pandas pivot_table - 如何从列值和列名的混合中创建一个 MultiIndex?

Pandas pivot_table - How to make a MultiIndex from a mix of column values and column names?

我对 Pandas 比较陌生。我有一个 DataFrame 的形式:

         A         B       C            D         E
0        1       1.1       a      23.7853   18.2647
1        1       1.2       a      23.7118   17.2387
2        1       1.1       b      24.1873   17.3874
3        1       1.2       b      23.1873   18.1748
4        2       1.1       a      24.1872   18.1847
...      ...     ...       ...     ...       ...

我想将其转换为 three-level MultiIndex,它由 A 列和 B 列以及 headers ["D", "E"] 列中的值构成。我还想将 B 中的值用作新列 headers,并将 D 和 E 列中的数据用作值。所有值都是 one-to-one(带有一些 NaN)。如果我理解正确,我需要使用 pivot_table() 而不是仅仅因为 MultiIndex 的 pivot() 。最终我想要一个 table 看起来像:

B                      1.1       1.2  ...
A    C  col-name
1    a         D   23.7853   23.7118  ...
               E   18.2647   17.2387  ...
     b         D   24.1873   23.1873  ...
               E   17.3874   18.1748  ...
2    a         D   24.1872   23.1987  ...
               E   18.1847   19.2387  ...
...  ...     ...     ...       ...    ...

我很确定答案是使用像

这样的命令
pd.pivot_table(df, columns=["B"], values=["D","E"], index=["A","C","???"])

我不确定要在“值”和“索引”参数中放入什么才能获得正确的行为。

如果我无法通过单个 pivot_table 命令完成此操作,我是否需要提前构建我的 Multi-Index?然后呢?

谢谢!

创建包含列 A, C, B 的多索引,然后使用 stack + unstack 重塑数据框

df.set_index(['A', 'C', 'B']).stack().unstack(-2)

B          1.1      1.2
A C                    
1 a D  23.7853  23.7118
    E  18.2647  17.2387
  b D  24.1873  23.1873
    E  17.3874  18.1748
2 a D  24.1872      NaN
    E  18.1847      NaN

可以使用pd.pivot_table() together with .stack(),如下:

(pd.pivot_table(df, index=['A', 'C'], columns='B', values=["D","E"])
   .rename_axis(columns=['col_name', 'B'])         # set axis name for ["D","E"] 
   .stack(level=0)
)

结果:

B                 1.1      1.2
A C col_name                  
1 a D         23.7853  23.7118
    E         18.2647  17.2387
  b D         24.1873  23.1873
    E         17.3874  18.1748
2 a D         24.1872      NaN
    E         18.1847      NaN