Python根据list对DataFrame自定义排序

更新时间:2026-08-26 13:38

Python要让DataFrame按一个list规定的业务顺序排列,最稳妥的做法是把目标列转成有序的 pandas.Categorical,再用 sort_values 排序。这样“高、中、低”或“待处理、处理中、已完成”会遵循你写进list的顺序,不会按字符串字母顺序排错。

Python根据list对DataFrame自定义排序

把list当作分类的顺序表。例如等级要按“高→中→低”展示,就把这三个值传给 categories,并明确设为 ordered=True。分类列排序时会读取categories的先后,而不是比较文字本身。

1、准备顺序和原始数据

下面的DataFrame故意把“中、低、高”打乱。order 中的排列就是最终想看到的业务顺序。

import pandas as pd
df = pd.DataFrame({
'等级': ['中', '低', '高', '中'],
'数量': [8, 3, 12, 5],
})
order = ['高', '中', '低']

2、转为有序分类并排序

把转换结果赋回原列,分组和再次排序都能沿用这套顺序。需要临时输出的场景可改用辅助列,原始文本列不会变化。

df['等级'] = pd.Categorical(
df['等级'],
categories=order,
ordered=True,
)
result = df.sort_values('等级').reset_index(drop=True)
print(result)

结果的等级顺序是高、中、低。图中展示的也是同一个关系:列表给出目标顺序,数据表经过分类排序后按该顺序重排。

Python根据list对DataFrame自定义排序

list与原数据不完全一致时怎么处理

先检查原列里是否出现了list未声明的值。categories未收录的值会变成缺失值,不要把这一步当成静默过滤。遇到“未知”或新增状态,需要决定它在业务上该排在哪里。

actual = set(df['等级'].astype('string').dropna())
unknown = actual - set(order)
if unknown:
print('需要处理的等级:', sorted(unknown))

参与排序的新增值应补进 order 的合适位置并重新转换。异常数据则应单独清洗或标记,再排序会比直接丢掉更容易追查。反过来,list比原数据多几个暂未出现的等级并不影响当前结果,它们只是暂时没有对应行。

同一等级还要按日期或数量排序

自定义顺序解决的是第一排序键。需要固定同一等级内部的先后,可把第二个字段一并交给 sort_values。例如希望同等级里数量大的排前面,可以这样写:

result = df.sort_values(
by=['等级', '数量'],
ascending=[True, False],
).reset_index(drop=True)
排序字段作用常见写法
等级按list固定业务顺序有序Categorical
数量或日期确定同等级内部先后追加到by列表

可打印 result['等级'].tolist() 核对顺序是否等于预期。这样既能保留list的业务含义,也能在每个分类内部得到可解释的排列结果。