
本文介绍两种可靠方法:一是将季度列转为有序分类(Categorical)类型后直接排序;二是使用 reindex() 配合 set_index() 按指定列表重排索引,适用于严格按给定顺序排列的场景。
本文介绍两种可靠方法:一是将季度列转为有序分类(categorical)类型后直接排序;二是使用 `reindex()` 配合 `set_index()` 按指定列表重排索引,适用于严格按给定顺序排列的场景。
在实际数据分析中,时间维度(如“Q1 2023”“Q4 2024”)往往不具备自然字典序或数值序,直接调用 sort_values() 会得到错误顺序(例如 "Q1 2024" 排在 "Q3 2023" 之前)。此时需显式定义顺序逻辑。以下是两种推荐方案:
✅ 方法一:使用有序 Categorical(推荐,语义清晰、可复用)
将 QuarterYear 列转换为有序分类类型,并按目标顺序设置类别层级,后续调用 sort_values() 即可自动按该顺序排序:
import pandas as pd
data = {'QuarterYear': ["Q1 2024", "Q2 2024", "Q3 2023", "Q3 2024", "Q4 2023", "Q4 2024"],
'data1': [5, 6, 2, 1, 10, 3], 'data2': [12, 4, 2, 7, 2, 9]}
df = pd.DataFrame(data)
# 定义期望顺序(必须完整覆盖所有唯一值)
sort_order = ["Q3 2023", "Q4 2023", "Q1 2024", "Q2 2024", "Q3 2024", "Q4 2024"]
# 转为有序 category,并指定 categories 和 ordered=True
df['QuarterYear'] = pd.Categorical(
df['QuarterYear'],
categories=sort_order,
ordered=True
)
# 直接排序(自动按 category 顺序)
df_sorted = df.sort_values('QuarterYear', ignore_index=True)
print(df_sorted)
输出:
QuarterYear data1 data2 0 Q3 2023 2 2 1 Q4 2023 10 2 2 Q1 2024 5 12 3 Q2 2024 6 4 4 Q3 2024 1 7 5 Q4 2024 3 9
⚠️ 注意事项:
categories必须包含QuarterYear列中所有可能出现的值,否则未声明的值会被设为NaN;- 若数据中存在新季度(如
"Q1 2025"),需提前扩展sort_order列表;- 此方法天然支持分组、绘图时保持顺序,是面向业务逻辑的稳健选择。
✅ 方法二:基于索引重排(精确匹配指定顺序)
若你已有一个完全匹配的顺序列表 sortTo,且要求严格按该列表顺序排列行(包括处理重复值或缺失值),推荐使用 set_index() + reindex() 组合:
# 保留原始 df,避免修改原数据
df_indexed = df.set_index('QuarterYear')
df_reindexed = df_indexed.reindex(sort_order).reset_index()
print(df_reindexed)
该方法会:
- 自动补全缺失季度行为
NaN(可加fill_value参数控制); - 保留
sort_order中重复项对应的多行(若原数据有重复季度); - 不依赖数据类型转换,适合一次性、强约束场景。
总结
- 首选有序 Categorical:适用于长期维护、需参与计算/可视化、顺序逻辑稳定的场景;
-
选用
reindex():适用于临时调整、顺序由外部输入确定、且要求 1:1 对应的场景; - 避免直接使用
df.reindex(sortTo)—— 因reindex()操作的是行索引,而sortTo是值列表,需先set_index()才能生效。
两种方法均无需第三方库,兼容 Pandas ≥ 1.0,兼顾可读性与工程健壮性。










