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

如何高效计算DataFrame中按ID分组的每行过去一年数值总和

高效计算个体过去一年数值总和的方法

嘿,完全懂你这种用apply处理大数据时卡到怀疑人生的感受!你的实现逻辑是对的,但逐行遍历整个DataFrame的做法时间复杂度是O(n²),数据量一大肯定慢得离谱。下面给你两种高效的替代方案,都是基于pandas的向量化操作,速度能提升几个数量级:

方案一:分组+时间滚动窗口(最直观)

这个方法利用pandas的rolling功能,针对每个ID的时间序列设置365天的滑动窗口,直接计算窗口内的数值总和,完全避免逐行循环:

import pandas as pd

# 1. 先确保日期列是datetime类型,并且数据按ID和日期排序(这步很关键)
df['Appointment Date'] = pd.to_datetime(df['Appointment Date'])
df = df.sort_values(['ID number', 'Appointment Date']).reset_index(drop=True)

# 2. 按ID分组,使用时间滚动窗口计算总和
key = 'numerical value'  # 替换成你的数值列名
df[f'{key}_last_year_sum'] = df.groupby('ID number').apply(
    lambda group: group.set_index('Appointment Date')[key]
                      .rolling(window='365D', closed='right')  # 窗口覆盖[当前日期-365天, 当前日期],匹配原逻辑的范围要求
                      .sum()
).reset_index(level=0, drop=True)

关键细节说明:

  • closed='right':确保当前行的日期被包含在窗口内,和你原代码的<=appt_date逻辑一致;滚动窗口的365天范围刚好对应>appt_date-365天的筛选(自动排除超过365天的历史记录)。
  • 必须先排序:分组后的时间序列必须有序,滚动窗口才能正确计算范围。

方案二:合并+累积求和(更极致的性能)

如果你的数据量特别大(比如百万级以上),可以用merge_asof结合累积求和的方式,性能会比rolling更优:

import pandas as pd

# 预处理:转换日期、排序
df['Appointment Date'] = pd.to_datetime(df['Appointment Date'])
df = df.sort_values(['ID number', 'Appointment Date']).reset_index(drop=True)

# 复制一份数据,将日期提前365天,用于后续匹配
df_shifted = df.copy()
df_shifted['Appointment Date'] = df_shifted['Appointment Date'] - pd.Timedelta(days=365)

# 用merge_asof找到每个ID、每个日期对应的"一年前"的位置
merged = pd.merge_asof(
    df,
    df_shifted[['ID number', 'Appointment Date', key]],
    on='Appointment Date',
    by='ID number',
    direction='backward'
)

# 计算累积求和,再减去一年前的累积和,得到过去一年的总和
df['cum_sum'] = df.groupby('ID number')[key].cumsum()
df[f'{key}_last_year_sum'] = df['cum_sum'] - merged[key].fillna(0)

逻辑解释:

  1. 先计算每个ID的累积求和cum_sum;
  2. 用merge_asof找到每个记录对应的"一年前"的累积和;
  3. 用当前累积和减去一年前的累积和,就得到了过去一年的数值总和,全程是向量化操作,没有任何循环。

为什么这两种方法更快?

原来的apply逐行处理时,每次都要遍历整个DataFrame筛选数据,相当于做了n次全表扫描;而上面的两种方法都是利用pandas的底层C优化向量化操作,时间复杂度是O(n log n)(主要来自排序),数据量越大,性能差距越明显。

你可以根据自己的数据规模选择方案:数据量中等用方案一(代码更易读),数据量超大用方案二(性能极致)。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.14 07:39:58