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

如何筛选DataFrame中每年每个ID记录数≤3的行?

如何筛选DataFrame中每个ID每年记录数≤3的行?

问题背景

现有一个包含ID和Date列的DataFrame,Date列类型为datetime64[ns],示例数据如下:

ID  Date
1   26.04.2011
1   21.10.2011
14  25.02.2010
14  08.07.2010
14  20.10.2010
14  07.01.2011
14  20.04.2011
14  02.07.2011
14  11.10.2011
14  23.01.2012
14  19.04.2012
14  22.10.2012
14  15.01.2013
14  06.05.2013
18  23.11.2012
18  05.06.2013
18  19.08.2013
18  11.04.2014
18  18.07.2014

需求是仅保留每个ID每年对应的Date记录数≤3的行,预期结果如下:

ID  Date
14  25.02.2010
14  08.07.2010
14  20.10.2010
14  07.01.2011
14  20.04.2011
14  02.07.2011
14  11.10.2011
14  23.01.2012
14  19.04.2012
14  22.10.2012

之前用groupby+size得到的是分组汇总结果,无法直接用来筛选原数据,需要调整方法。


解决方案

核心思路是:用transform方法将分组统计的记录数映射到原DataFrame的每一行,再基于这个值筛选符合条件的行。

方法1:简洁写法(一步到位)

# 直接按ID和年份分组,用transform获取每行对应的组记录数,再筛选
result = df[df.groupby(['ID', df['Date'].dt.year])['Date'].transform('size') <= 3]

方法2:分步拆解(更易理解)

如果想清晰查看中间步骤,可以拆分执行:

# 1. 从Date列提取年份,生成辅助列
df['year'] = df['Date'].dt.year

# 2. 按ID和year分组,计算每组的记录数,并映射到每行
df['record_count'] = df.groupby(['ID', 'year'])['Date'].transform('size')

# 3. 筛选记录数≤3的行,最后移除辅助列
result = df[df['record_count'] <= 3].drop(columns=['year', 'record_count'])

原理说明

  • groupby(['ID', df['Date'].dt.year]):按ID和年份分组,确保统计的是每个ID在每一年的记录数
  • transform('size'):将分组后的统计结果(每组的记录数)广播到该组的每一行,让原DataFrame的每一行都能拿到自己所在组的记录数
  • 最后通过布尔索引筛选出记录数≤3的行,即可得到符合需求的结果

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.04 05:35:28