You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何对Pandas多索引列执行melt:保留AA列逆透视BB列

处理多层索引列的Pandas DataFrame逆透视需求

问题场景

有一个带多层索引列的Pandas DataFrame,示例代码及结构如下:

import pandas as pd

df = pd.DataFrame({('AA', 'A'): {0: 'a', 1: 'b', 2: 'c'},
               ('AA', 'B'): {0: 'd', 1: 'e', 2: 'f'},
               ('AA', 'C'): {0: 'g', 1: 'h', 2: 'i'},
               ('BB', 'D'): {0: 1, 1: 2, 2: 3},
               ('BB', 'E'): {0: 4, 1: 5, 2: 6}})

DataFrame结构展示:

AA       BB   
   A  B  C  D  E
0  a  d  g  1  4
1  b  e  h  2  5
2  c  f  i  3  6

需要将BB层级下的所有列执行逆透视(unpivot),同时将AA层级下的所有列作为标识列,最终目标格式:

AA             BB      
   A  B  C Variable Value
0  a  d  g        D     1
1  b  e  h        D     2
2  c  f  i        D     3
3  a  d  g        E     4
4  b  e  h        E     5
5  c  f  i        E     6

尝试过的方法及问题

  • 直接指定层级名称的方式无法运行:
df.melt(id_vars=['AA'], value_vars=['BB'], col_level=0)
  • 另一种方法可实现类似效果,但不够Pythonic,还会生成额外列且扁平化多索引结构:
df.melt(id_vars=[('AA','A'),('AA','B'), ('AA','C')], value_vars=[('BB','D'),('BB','E')])

得到的结果:

(AA, A) (AA, B) (AA, C) variable_0 variable_1  value
0       a       d       g         BB          D      1
1       b       e       h         BB          D      2
2       c       f       i         BB          D      3
3       a       d       g         BB          E      4
4       b       e       h         BB          E      5
5       c       f       i         BB          E      6

正确实现方案

方法1:列索引筛选+melt后重构层级

通过层级筛选动态获取标识列和待逆透视列,再通过melt的参数指定新列的层级结构:

# 动态筛选AA层级的所有列作为标识列,BB层级的所有列作为待逆透视列
id_vars = df.columns[df.columns.get_level_values(0) == 'AA']
value_vars = df.columns[df.columns.get_level_values(0) == 'BB']

# 执行逆透视,指定变量名和值的层级结构
result = df.melt(
    id_vars=id_vars,
    value_vars=value_vars,
    var_name=['BB', 'Variable'],
    value_name=['BB', 'Value'],
    col_level=1  # 提取子层级的列名作为Variable
)

# 调整列顺序,保持AA列在前
result = result[id_vars.tolist() + [('BB', 'Variable'), ('BB', 'Value')]]

方法2:拆分DataFrame后合并(更直观)

将原DataFrame拆分为AA和BB两个子DataFrame,单独逆透视BB后再合并:

# 拆分出AA和BB对应的子DataFrame
df_aa = df['AA']
df_bb = df['BB']

# 对BB执行逆透视,保留原索引以匹配AA数据
df_bb_unpivot = df_bb.melt(var_name='Variable', value_name='Value', ignore_index=False)

# 合并AA和逆透视后的BB,重置索引
result = pd.concat([df_aa, df_bb_unpivot], axis=1).reset_index(drop=True)

# 重构列的多层索引
result.columns = pd.MultiIndex.from_tuples(
    [('AA', col) for col in df_aa.columns] + [('BB', 'Variable'), ('BB', 'Value')]
)

两种方法最终都能得到目标格式的结果:

AA             BB      
   A  B  C Variable Value
0  a  d  g        D     1
1  b  e  h        D     2
2  c  f  i        D     3
3  a  d  g        E     4
4  b  e  h        E     5
5  c  f  i        E     6

内容的提问来源于stack exchange,提问作者Jeskrt

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.07 23:01:34