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

pandas按id分组:completion_dt重复时保留Maturity_dt最大行

需求说明

使用pandas处理DataFrame时,需实现如下行筛选逻辑:针对每个id分组,若组内completion_dt字段值存在重复,仅保留重复项中Maturity_dt字段为最大日期的行,删除其余重复行。

  • 原始测试数据:
id  Maturity_dt     score   completion_dt
1   2020-12-31      12      2022-06-24
2   2020-12-31      8       2022-03-30
2   2019-12-31      0       2022-03-30
2   2018-12-31      0       2021-08-24
3   2022-12-31      15      2022-05-31
2   2021-12-31      12      2022-05-31
  • 期望输出结果:
id  Maturity_dt     score   completion_dt
1   2020-12-31      12      2022-06-24
2   2020-12-31      8       2022-03-30
2   2018-12-31      0       2021-08-24
3   2022-12-31      15      2022-05-31
2   2021-12-31      12      2022-05-31
原有代码问题

原有实现代码如下:

df = df.sort_values('Maturity_dt').drop_duplicates(subset=['completion_dt', 'id'], keep='last')

问题出在两个地方:

  1. 没有提前将日期列转换为datetime类型,如果列是字符串格式,极端场景下字符串字典序和真实日期顺序不一致会导致排序错误
  2. 排序默认采用升序,虽然keep='last'理论上可以取到同组最大值,但如果存在同组内Maturity_dt为空值、格式异常值的情况,排序逻辑会不符合预期
正确实现方案

运行前先做日期类型转换,规避格式导致的计算异常:

import pandas as pd

# 统一转换日期列为datetime类型
df['Maturity_dt'] = pd.to_datetime(df['Maturity_dt'])
df['completion_dt'] = pd.to_datetime(df['completion_dt'])

方案1:排序去重法

逻辑直观,性能更好,适合大数据量场景:

# 按Maturity_dt降序排序,同id+completion_dt组的第一行就是Maturity_dt最大的行
df_res = df.sort_values(by='Maturity_dt', ascending=False, ignore_index=True)
# 按id和completion_dt联合去重,保留第一条即可
df_res = df_res.drop_duplicates(subset=['id', 'completion_dt'], keep='first')

如果需要保留原始数据的行顺序,去重后可以再按原始索引排序:

df_res = df_res.sort_index()

方案2:分组过滤法

逻辑直白,不需要提前调整行顺序:

# 匹配每行所属id+completion_dt组的最大Maturity_dt,保留值相等的行即可
df_res = df[df.groupby(['id', 'completion_dt'])['Maturity_dt'].transform('max') == df['Maturity_dt']]

两种方案运行后输出结果和期望结果完全一致。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 23:12:17