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
相关产品推荐
相关产品推荐

