Pandas多索引分组:按指定规则转换DataFrame结构
Pandas数据结构转换解决方案
核心需求回顾
- ID分组在顶部且不重复
- 按指定的
id_sort和field_sort规则排序 - DATE标签与字段列同层级展示
分步实现代码
1. 数据初始化与排序预处理
import pandas as pd # 原始数据 data = [['id', 'date', 'b_field', 'a_field'], ['XYX', '01/01/2024', 100, 101], ['XYX', '01/02/2024', 200, 201], ['ABC', '01/01/2024', 300, 301], ['ABC', '01/02/2024', 400, 401]] id_sort=['ABC', 'XYX'] # 修正原输入中的拼写错误(XYZ→XYX) field_sort=['a_field', 'b_field'] df = pd.DataFrame(data[1:], columns=data[0]) # 设置ID的自定义排序规则,转为分类类型保证排序优先级 df['id'] = pd.Categorical(df['id'], categories=id_sort, ordered=True) # 按ID、日期排序,确保基础数据顺序正确 df = df.sort_values(['id', 'date'])
2. 重塑数据结构,实现DATE与字段同列
# 将宽表转为长表,把字段列转为行维度 melted_df = df.melt( id_vars=['id', 'date'], value_vars=field_sort, var_name='field', value_name='value' ) # 设置字段的自定义排序规则 melted_df['field'] = pd.Categorical(melted_df['field'], categories=field_sort, ordered=True) melted_df = melted_df.sort_values(['id', 'date', 'field']) # 生成DATE专属行,确保DATE标签与字段同列 date_rows = melted_df[['id', 'date']].drop_duplicates() date_rows = date_rows.assign(field='DATE', value=date_rows['date']) # 合并DATE行与字段行,重新排序保证DATE在每组最前 combined_df = pd.concat([date_rows, melted_df]) combined_df['field'] = pd.Categorical(combined_df['field'], categories=['DATE'] + field_sort, ordered=True) combined_df = combined_df.sort_values(['id', 'date', 'field']) # 构建最终结构:ID作为索引(分组不重复),DATE和字段作为列 result_df = combined_df.set_index(['id', 'date', 'field']).unstack('field') result_df = result_df.droplevel(0, axis=1).reset_index(level='date', drop=True)
3. 最终结果展示
执行以下代码查看输出:
print(result_df)
输出结果:
DATE a_field b_field id ABC 01/01/2024 301 300 ABC 01/02/2024 401 400 XYX 01/01/2024 101 100 XYX 01/02/2024 201 200
问题针对性解决
- ID分组不重复:通过将ID设为索引,可视化时自动实现顶部分组且重复ID仅显示一次(若需完全隐藏重复ID,可使用
result_df.style.hide_index(subset=['id'])) - DATE标签层级错误:通过生成独立的DATE行并设置分类排序,确保DATE与字段处于同一列层级
- 空值/元组问题:使用
melt+concat的标准数据重塑流程,避免错误的列名拼接或值映射,保证所有数据正确显示 - 自定义排序:全程使用
pd.Categorical指定排序规则,严格遵循id_sort和field_sort的要求
内容的提问来源于stack exchange,提问作者mike01010
相关产品推荐
相关产品推荐

