Pandas多层列头:将一级分类列转为值列并合并同名列的实现方法
问题核心
reset_index()仅能处理行方向的多层索引,而你当前的转换需求是针对列方向的多层表头,操作对象不匹配,因此无法得到预期效果。
具体实现步骤
1. 确认原始列结构
先运行以下代码验证多层列层级是否符合预期:
print(df.columns) # 正常应输出类似的MultiIndex结构: # MultiIndex([('Person', 'Name'), # ('Category1', 'Date'), # ('Category1', 'Price'), # ('Category2', 'Date'), # ('Category2', 'Price')], )
2. 拆分无需纵向拼接的公共列
Person层级下只有Name一个公共字段,不需要纵向拆分,先将其提取为普通列结构:
# 提取Person层级的所有列,拍平为单层级列 person_common = df['Person'].copy() person_common.columns = ['Name']
3. 对Category类列做纵向拼接
这部分的每个Category下都有同名的Date、Price字段,需要转成行、同时把Category名作为新列的取值:
# 提取所有Category开头的层级列 category_part = df.loc[:, df.columns.get_level_values(0).str.startswith('Category')].copy() # 先把原始行索引保存为临时列,避免后续排序丢失原始行顺序 category_part['original_idx'] = category_part.index # 交换列层级,让Date、Price跑到第一层,Category名放到第二层 category_part.columns = category_part.columns.swaplevel(0, 1) # 将第二层的Category名从列索引转为行索引,自动完成Date、Price的纵向拼接 # pandas版本<2.1时去掉future_stack参数即可 category_part = category_part.stack(level=1, future_stack=True) # 将转为行索引的Category名改为普通列,同时清理索引名 category_part = category_part.rename_axis(index={'level_1': 'Category'}).reset_index(level=1)
4. 合并得到最终结果
由于两步提取的内容都保留了原始行索引的对应关系,可直接对齐合并,再调整顺序匹配目标效果:
# 按原始行索引对齐合并公共列和拆分后的分类列 result = person_common.join(category_part) # 先按Category分组,再按原始行顺序排序,匹配示例的行顺序 result = result.sort_values(by=['Category', 'original_idx']) # 删除临时的原始索引列,重置为连续索引 result = result.drop(columns=['original_idx']).reset_index(drop=True) # 若需要将索引调整为从1开始,匹配示例格式 result.index = result.index + 1
效果验证
运行后得到的result表结构完全匹配目标结果:
Name Date Price Category 1 Bob 1999 1 Category1 2 Alice 1992 8 Category1 3 Alice 1994 19 Category1 4 Bob 1994 2 Category2 5 Alice 1992 3 Category2 6 Alice 1990 6 Category2
内容的提问来源于stack exchange,提问作者Chau362
相关产品推荐
相关产品推荐

