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

Pandas多级列DataFrame自定义列层级排序问题

问题

现有如下数据:

from pandas import Timestamp
import pandas as pd

values = [['IDX100', 'field1', Timestamp('1999-02-01 05:00:00'), '101'],
       ['IDX100', 'field1', Timestamp('1999-02-02 05:00:00'), '102'],
       ['IDX100', 'field1', Timestamp('1999-02-03 05:00:00'), '103'],
       ['IDX200', 'field1', Timestamp('1999-02-01 05:00:00'), '601'],
       ['IDX200', 'field1', Timestamp('1999-02-02 05:00:00'), '602'],
       ['IDX200', 'field1', Timestamp('1999-02-03 05:00:00'), '603'],
       ['IDX100', 'field2', Timestamp('1999-02-01 05:00:00'), '201'],
       ['IDX100', 'field2', Timestamp('1999-02-02 05:00:00'), '202'],
       ['IDX100', 'field2', Timestamp('1999-02-03 05:00:00'), '203'],
       ['IDX200', 'field2', Timestamp('1999-02-01 05:00:00'), '701'],
       ['IDX200', 'field2', Timestamp('1999-02-02 05:00:00'), '702'],
       ['IDX200', 'field2', Timestamp('1999-02-03 05:00:00'), '703'],
       ['IDX100', 'field3', Timestamp('1999-02-01 05:00:00'), '301'],
       ['IDX100', 'field3', Timestamp('1999-02-02 05:00:00'), '302'],
       ['IDX100', 'field3', Timestamp('1999-02-03 05:00:00'), '303'],
       ['IDX200', 'field3', Timestamp('1999-02-01 05:00:00'), '801'],
       ['IDX200', 'field3', Timestamp('1999-02-02 05:00:00'), '802'],
       ['IDX200', 'field3', Timestamp('1999-02-03 05:00:00'), '803']]

df = pd.DataFrame(values, columns = ['identifier', 'code', 'date', 'value'])

执行透视操作后得到多级列结构:

df = df.pivot(index=['date'], columns=['identifier', 'code'], values=['value'])

输出结果:

value                                   
identifier          IDX100 IDX200 IDX100 IDX200 IDX100 IDX200
code                field1 field1 field2 field2 field3 field3
date                                                         
1999-02-01 05:00:00    101    601    201    701    301    801
1999-02-02 05:00:00    102    602    202    702    302    802
1999-02-03 05:00:00    103    603    203    703    303    803

期望得到的输出样式:

identifier           IDX100                IDX200 
code                 field3 field2 field1  field3 field2 field1
date                                                         
1999-02-01 05:00:00    301    201    101   801    701    601
1999-02-02 05:00:00    302    202    102   802    702    602
1999-02-03 05:00:00    303    203    103   803    703    603

尝试过df = df.reindex(sorted(df.columns), axis=1),但只能保持code层级默认顺序field1、field2、field3,无法实现自定义排序(如field3、field2、field1),需要解决这个问题。

解决方案

有两种方式可以实现自定义的多级列排序:

方法一:透视后重排列索引

  1. 先定义自定义的code顺序:
custom_code_order = ['field3', 'field2', 'field1']
  1. 获取唯一的identifier列表:
identifiers = df.columns.get_level_values('identifier').unique()
  1. 构造目标列索引的元组列表(结合最上层的value层级):
target_columns = [('value', ident, code) for ident in identifiers for code in custom_code_order]
  1. 使用reindex重新排列列:
df = df.reindex(columns=target_columns)

方法二:透视前设置分类排序

这种方式不需要后续重排,一步到位得到目标结构:

  1. 将code列转为分类类型并指定自定义顺序:
custom_code_order = ['field3', 'field2', 'field1']
df['code'] = pd.Categorical(df['code'], categories=custom_code_order, ordered=True)
  1. 执行透视操作:
df = df.pivot(index=['date'], columns=['identifier', 'code'], values=['value'])

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.27 00:05:38