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

如何用Pandas DataFrame统计近30天内的记录出现次数

解决Pandas中按ID统计近30天内出现次数的问题

步骤1:确保日期列是datetime类型

首先需要将字符串格式的日期转换为Pandas的datetime类型,否则无法进行时间运算:

import pandas as pd

# 构造示例数据(匹配你的需求场景)
data = {
    'ID': ['001', '001', '001', '002', '002', '002'],
    'date': ['2022-01-01', '2022-01-04', '2022-02-05', '2022-01-02', '2022-01-28', '2022-03-01']
}
df = pd.DataFrame(data)

# 转换日期列
df['date'] = pd.to_datetime(df['date'])

步骤2:按ID分组+时间窗口滚动统计

使用groupby按ID分组,结合rolling的时间窗口功能,指定窗口为30天,同时设置closed='left'排除当前行(因为我们要统计的是当前日期之前30天内的记录):

# 先按ID和日期排序,确保滚动窗口计算逻辑正确
df = df.sort_values(['ID', 'date'])

# 计算近30天内的出现次数
df['occurrences_last_month'] = df.groupby('ID')['date'].rolling('30D', closed='left').count().reset_index(level=0, drop=True)

执行后得到的结果完全匹配预期:

IDdateoccurrences_last_month
00012022-01-010.0
10012022-01-041.0
20012022-02-051.0
30022022-01-020.0
40022022-01-281.0
50022022-03-010.0

为什么你的方法没生效?

  • 未按ID分组:直接对整个DataFrame计算会把不同ID的记录混在一起统计,结果自然错误。
  • 滚动窗口参数错误:如果没设置closed='left',默认会包含当前行,导致计数多1;或者误用了行数窗口而非时间窗口('30D')。
  • 日期未排序:滚动窗口依赖有序的日期,未排序会导致统计范围混乱。

备选方法(小数据量适用)

如果数据量不大,也可以用apply逐行计算,逻辑更直观,但效率低于滚动窗口:

df['occurrences_last_month'] = df.apply(
    lambda row: len(df[(df['ID'] == row['ID']) & 
                      (df['date'] >= row['date'] - pd.Timedelta(days=30)) & 
                      (df['date'] < row['date'])]),
    axis=1
)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.20 07:15:37