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

如何基于日期和姓名转换Pandas DataFrame实现周期值统计

Pandas分组统计固定时间窗口数值和解决方案

你当前的实现逻辑是按月度重采样后做累计值计算,和需求中「以全局最新日期为基准,回溯固定自然日窗口求和」的逻辑不匹配,按以下步骤实现即可得到预期输出:

  • 预处理日期字段,确定统计基准
    首先将date列转换为pandas的datetime类型,取全表最大日期作为时间窗口的统计基准。注意:不要按分组单独取每个用户的最新日期,否则会出现统计口径不一致的问题:

    import pandas as pd
    
    # 转换日期列为标准datetime格式
    df['date'] = pd.to_datetime(df['date'])
    # 取全表最新日期作为统一统计基准
    base_date = df['date'].max()
    
  • 分组计算两个时间窗口的value总和
    按name字段分组,分别筛选出落在近30天、近365天窗口内的记录,对value字段求和:

    result = df.groupby('name', as_index=False).agg(
        Last_30_days=('value', lambda s: s[df.loc[s.index, 'date'] >= base_date - pd.Timedelta(days=30)].sum()),
        Last_365_days=('value', lambda s: s[df.loc[s.index, 'date'] >= base_date - pd.Timedelta(days=365)].sum())
    ).rename(columns={'name': 'Name'})
    

结果验证

执行代码后输出的结果和预期完全一致:

Name  Last_30_days  Last_365_days
0  Anna             5             15
1   Jim             3             10

原代码问题说明

  • resample('MS')是按月度首日为节点做时间分箱,和需求的固定自然日滚动窗口逻辑完全不符
  • 后续调用的cumsum()是按时间顺序做累计求和,不是从基准日期回溯指定范围的条件求和,因此无法得到目标结果

大数据量优化方案

如果数据集规模较大,可以提前给每行数据打窗口标记,减少分组计算时的重复判断,执行效率更高:

# 提前标记每行是否属于对应时间窗口
df['in_30d'] = df['date'] >= base_date - pd.Timedelta(days=30)
df['in_365d'] = df['date'] >= base_date - pd.Timedelta(days=365)

result = df.groupby('name', as_index=False).agg(
    Last_30_days=('value', lambda s: s[df.loc[s.index, 'in_30d']].sum()),
    Last_365_days=('value', lambda s: s[df.loc[s.index, 'in_365d']].sum())
).rename(columns={'name': 'Name'})

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 15:06:21