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

Pandas分组排序需求:按组内col_b最小值排序分组并组内排序

解决Pandas分组后按组内最小值排序分组的问题

原始数据

col_a      col_b
0     b 2022-01-01
1     a 2022-01-02
2     c 2022-10-03
3     b 2022-10-01
4     a 2022-10-03
5     c 2022-10-02

需求

  • 按col_a列进行groupby分组
  • 每个分组内按col_b列排序
  • 各组按col_b列的最小值排序,使最小值最早的分组排在最前

期望输出

col_a      col_b
0     b 2022-01-01 # b组col_b最小值最早,排在首位
1     b 2022-10-01 # b组内按col_b排序后的下一条数据
2     a 2022-01-02 # a组col_b最小值次之
3     a 2022-10-03
5     c 2022-10-02 # 注:原期望输出c组顺序存在笔误,组内按col_b排序后此条应在前
4     c 2022-10-03

用户尝试的代码(无法实现完整需求)

import pandas as pd
df = pd.DataFrame({
    "col_a": ['b', 'a', 'c', 'b', 'a', 'c'],
    'col_b' :   pd.to_datetime(["2022/01/01","2022/01/02","2022/10/03","2022/10/01", "2022/10/03","2022/10/02"])
})

desired_df = pd.DataFrame({
    "col_a": ['b', 'b', 'a', 'a', 'c', 'c'],
    'col_b' :  pd.to_datetime(["2022/01/01", "2022/10/01","2022/01/02", "2022/10/03","2022/10/03", "2022/10/02"])
})

print(df.groupby('col_a').apply(lambda x: x.sort_values('col_b')))

上述代码仅能完成组内排序,但无法按各组col_b的最小值调整整个DataFrame的分组顺序。

正确解决方案

核心思路是添加辅助列存储每组col_b的最小值,通过多列排序实现需求:

import pandas as pd

df = pd.DataFrame({
    "col_a": ['b', 'a', 'c', 'b', 'a', 'c'],
    'col_b' : pd.to_datetime(["2022/01/01","2022/01/02","2022/10/03","2022/10/01", "2022/10/03","2022/10/02"])
})

# 1. 添加辅助列,存储每个分组的col_b最小值
df['min_col_b'] = df.groupby('col_a')['col_b'].transform('min')

# 2. 按辅助列确定分组顺序,再按col_a和col_b完成组内排序
result = df.sort_values(by=['min_col_b', 'col_a', 'col_b']).drop(columns='min_col_b')

print(result)

输出结果

col_a      col_b
0     b 2022-01-01
3     b 2022-10-01
1     a 2022-01-02
4     a 2022-10-03
5     c 2022-10-02
2     c 2022-10-03

步骤解释

  • transform('min')会为每组的所有行填充该组col_b的最小值,以此作为分组排序的依据。
  • 多列排序时,先按min_col_b确定分组的整体顺序,再按col_a保证同组数据聚合,最后按col_b完成组内排序。
  • 最后删除辅助列,得到符合需求的干净结果。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.01 19:10:29