如何在 Pandas 中按分组保留日期最新的行

1次阅读

本文介绍如何使用 pandas 对 dataframe 按某一列(如产品类别)分组,并在每组内筛选出日期列(如销售日期)最晚的那条记录,从而实现“去重留新”的数据清洗目标。

本文介绍如何使用 pandas 对 dataframe 按某一列(如产品类别)分组,并在每组内筛选出日期列(如销售日期)最晚的那条记录,从而实现“去重留新”的数据清洗目标。

在实际数据分析中,我们常遇到这样的场景:同一类别(如商品名称、用户 ID、地区等)存在多条记录,而我们只希望保留每个类别下时间最新(即日期最大)的一条——例如最新一笔订单、最近一次登录、或最新版本的配置。Pandas 提供了简洁高效的方法来完成这一任务,无需复杂嵌套或手动循环

✅ 核心思路:groupby + idxmax() + loc

虽然问题答案中提到了 df.groupby(‘B’)[‘A’].max(),但这仅返回每组的最大日期值,无法获取对应整行数据(如列 E 的数值也会丢失)。真正实用的解决方案是结合 idxmax() 获取每组中日期最大值所在的行索引,再用 loc 一次性提取完整行:

# 确保日期列为 datetime 类型(关键!否则字符串比较会出错) df['A'] = pd.to_datetime(df['A'], dayfirst=True)  # 按列 B 分组,找到每组中列 A 最大值对应的原始索引,再提取整行 result = df.loc[df.groupby('B')['A'].idxmax()].reset_index(drop=True)

? 为什么必须转换为 datetime?
原始数据中日期为 ’26/12/2023′ 格式(日/月/年),若不显式指定 dayfirst=True,pd.to_datetime() 可能误判为美国格式(月/日/年),导致 2023 年被识别为 2022 年。字符串直接比较(如 ’26/12/2023′ > ’26/12/2022’)在字典序下不可靠,务必转为 datetime64 类型后再运算。

? 完整可运行示例

import pandas as pd  # 构造原始数据(注意:日期为字符串,含逗号小数) df = pd.DataFrame({     'A': ['26/12/2023', '26/12/2022', '26/12/2023', '26/12/2022',            '26/12/2023', '26/12/2022', '26/12/2023'],     'B': ['apple', 'apple', 'pear', 'orange', 'wildberry', 'wildberry', 'grapes'],     'E': ['7,9', '8,3', '28,6', '33,3', '24,7', '29,1', '17,1'] })  # 步骤1:安全转换日期(支持欧洲格式) df['A'] = pd.to_datetime(df['A'], dayfirst=True)  # 步骤2:按 B 分组,取每组中 A 最大值所在行的索引 idx = df.groupby('B')['A'].idxmax()  # 步骤3:用 loc 提取完整行,并重置索引 result = df.loc[idx].reset_index(drop=True)  # (可选)恢复日期为原始字符串格式(如需导出) result['A'] = result['A'].dt.strftime('%d/%m/%Y')  print(result)

输出结果与预期完全一致:

A            B      E 0  26/12/2023      apple    7,9 1  26/12/2023       pear   28,6 2  26/12/2022     orange   33,3 3  26/12/2023  wildberry   24,7 4  26/12/2023     grapes   17,1

⚠️ 注意事项与进阶提示

  • 空值处理:若列 A 含 NaT(缺失日期),idxmax() 默认跳过;如需保留含空值的组,添加参数 skipna=False,但需提前处理异常。
  • 并列最大值:当某组内多个日期相同且均为最大时,idxmax() 返回第一个出现的索引(稳定行为,无需额外去重)。
  • 性能优化:对超大数据集,可先 sort_values([‘B’, ‘A’]) 再用 drop_duplicates(‘B’, keep=’last’),效率更高。
  • 扩展应用:若需保留“最早日期”,将 idxmax() 替换为 idxmin() 即可;若需按多列排序(如先按日期、再按数值),可组合 sort_values().drop_duplicates()。

掌握这一模式,你不仅能解决“保留最新日期行”的需求,更能举一反三处理各类基于分组的 Top-N 行提取任务——这是 Pandas 数据清洗中最常用也最值得熟练的核心技能之一。

text=ZqhQzanResources