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

Python DataFrame按单列排序重排行时保留另一列原有顺序的方法

Pandas 保留列原始出现顺序的分组排序实现

现有数据集

Name Year  Date Value
x    year1 date1 v1
x    year1 date2 v2
x    year1 date3 v3
x    year2 date1 v4
x    year2 date2 v5
x    year2 date3 v6
z    year1 date1 v7
z    year1 date2 v8
z    year1 date3 v9
z    year2 date1 v10
z    year2 date2 v11
z    year2 date3 v12
y    year1 date1 v13
y    year1 date2 v14
y    year1 date3 v15
y    year2 date1 v16
y    year2 date2 v17
y    year2 date3 v18

排序要求

  • 保持Name列原始出现顺序x、z、y不变,不按字典序重排
  • 每个Name分组内部按Date列排序
  • 同一Date下year1、year2的行相邻,且year1在前

问题原因

直接使用df.sort_values(['Name', 'Date'])时,pandas会默认对字符串类型的Name列按字典序排序,y的字典序小于z,因此最终输出Name顺序为x、y、z,不符合要求;同时代码缺少Year作为排序键,无法保证同一日期下年份顺序正确。

实现方案

方案1:指定分类顺序后排序

先提取Name列的原始出现顺序,将列转为指定顺序的分类类型,再按多键排序即可,性能更优适合大数据集:

import pandas as pd

# 提取Name列首次出现的顺序,去重保留原始先后
name_sort_order = df['Name'].drop_duplicates().tolist()
# 将Name列转为自定义顺序的分类类型
df['Name'] = pd.Categorical(df['Name'], categories=name_sort_order, ordered=True)
# 按Name、Date、Year三个维度排序
df_sorted = df.sort_values(by=['Name', 'Date', 'Year'])

方案2:分组排序保留原始分组顺序

使用groupby的sort=False参数关闭分组时的自动排序,保留Name原始出现顺序,再对每个分组内部单独排序:

df_sorted = df.groupby('Name', sort=False, group_keys=False).apply(
    lambda group: group.sort_values(by=['Date', 'Year'])
)

两种方案输出结果完全符合预期:

Name Year  Date Value
x    year1 date1 v1
x    year2 date1 v4
x    year1 date2 v2
x    year2 date2 v5
x    year1 date3 v3
x    year2 date3 v6
z    year1 date1 v7
z    year2 date1 v10
z    year1 date2 v8
z    year2 date2 v11
z    year1 date3 v9
z    year2 date3 v12
y    year1 date1 v13
y    year2 date1 v16
y    year1 date2 v14
y    year2 date2 v17
y    year1 date3 v15
y    year2 date3 v18

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.26 13:24:27