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),需要解决这个问题。
解决方案
有两种方式可以实现自定义的多级列排序:
方法一:透视后重排列索引
- 先定义自定义的code顺序:
custom_code_order = ['field3', 'field2', 'field1']
- 获取唯一的identifier列表:
identifiers = df.columns.get_level_values('identifier').unique()
- 构造目标列索引的元组列表(结合最上层的
value层级):
target_columns = [('value', ident, code) for ident in identifiers for code in custom_code_order]
- 使用
reindex重新排列列:
df = df.reindex(columns=target_columns)
方法二:透视前设置分类排序
这种方式不需要后续重排,一步到位得到目标结构:
- 将
code列转为分类类型并指定自定义顺序:
custom_code_order = ['field3', 'field2', 'field1'] df['code'] = pd.Categorical(df['code'], categories=custom_code_order, ordered=True)
- 执行透视操作:
df = df.pivot(index=['date'], columns=['identifier', 'code'], values=['value'])
内容的提问来源于stack exchange,提问作者mike01010
相关产品推荐
相关产品推荐

