如何将Pandas多层索引DataFrame unstack为单主体占一行的宽表
Pandas多层索引转指定结构宽表实现方案
直接给你可运行的完整代码,逻辑拆分为固定属性提取、计算字段展开、表合并三个步骤,完全适配你描述的场景:
1. 模拟符合场景的测试数据集(你可以跳过这步直接用自己的DataFrame)
import pandas as pd import numpy as np # 构造多层索引:第一层为name,第二层为每个name下的序列index multi_index = pd.MultiIndex.from_tuples( [('user1', 0), ('user1', 1), ('user1', 2), ('user2', 0), ('user2', 1), ('user3', 0)], names=['name', 'seq_idx'] ) df = pd.DataFrame({ 'f1': [10, np.nan, np.nan, 20, np.nan, 30], 'f2': ['x', np.nan, np.nan, 'y', np.nan, 'z'], 'f3': [True, np.nan, np.nan, False, np.nan, True], 'calc1': [0.1, 0.4, 0.6, 0.2, 0.7, 0.3], 'calc2': [10, 40, 60, 20, 70, 30], 'calc3': [100, 400, 600, 200, 700, 300] }, index=multi_index)
2. 核心转换代码
# 第一步:提取每个name对应的f1~f3固定属性 attr_df = df[['f1', 'f2', 'f3']].groupby(level='name').first() # 第二步:将calc字段按序列index展开为宽表,空缺位置自动补NaN calc_wide = df[['calc1', 'calc2', 'calc3']].unstack(level='seq_idx') # 重命名列,拼接为calc1_1这类要求的格式 calc_wide.columns = [f"{col}_{seq}" for col, seq in calc_wide.columns] # 第三步:合并两张表得到最终结果 result = attr_df.join(calc_wide).reset_index()
场景适配说明
- 如果你的原数据不是多层索引,只要有
name和序列index两个字段,先执行df = df.set_index(['name', '你的序列index字段名'])转成多层索引,再跑上面的代码即可 - 不存在的序列对应的calc字段会自动填充NaN,不需要额外处理
- 如果你不需要保留序列index=0对应的calc字段,只需要在构造
calc_wide前过滤掉对应行即可:df = df[df.index.get_level_values('seq_idx') != 0]
内容的提问来源于stack exchange,提问作者Drewaight
相关产品推荐
相关产品推荐

