如何用Pandas计算客户过去365天的滚动累计值?
Pandas计算每个客户过去365天滚动累计值的解决方法
错误原因分析
你遇到的ValueError是因为:
- 你将
date设置为多层索引(['customer', 'date'])的一部分,此时date不再是DataFrame的列,rolling的on='date'参数无法找到对应列。 - 代码没有按客户分组,全局计算滚动和会混淆不同客户的时间线,不符合“每个客户独立计算”的需求。
正确实现方法
步骤1:预处理数据
首先需要将date列转换为datetime类型,这是Pandas时间窗口滚动计算的前提:
import pandas as pd # 原始数据 dates = ['2016-07-29', '2016-08-01', '2017-01-12', '2017-10-23', '2018-03-03', '2018-03-06', '2019-03-16', '2017-04-07', '2017-04-09', '2018-02-11', '2018-05-12', '2019-05-10'] customer = [1,1,1,1,1,1,1,2,2,2,2,2] daily_total = [100,50,80,180,0,40,500,50,230,80,0,0] df = pd.DataFrame({ 'date': dates, 'customer': customer, 'daily_total_per_customer': daily_total }) # 将date转为datetime类型 df['date'] = pd.to_datetime(df['date'])
步骤2:按客户分组计算滚动累计
这里提供两种简洁的实现方式:
方式一:分组后链式调用
# 按客户和日期排序,保证时间顺序正确 df = df.sort_values(['customer', 'date']) # 分组计算每个客户的365天滚动和 df['rolling_total'] = df.groupby('customer').rolling( '365D', on='date' )['daily_total_per_customer'].sum().reset_index(level=0, drop=True)
方式二:自定义分组处理函数(更直观)
def compute_rolling_sum(group): # 组内按日期排序 group_sorted = group.sort_values('date') # 设置日期为索引,计算滚动窗口 group_sorted = group_sorted.set_index('date') group_sorted['rolling_total'] = group_sorted['daily_total_per_customer'].rolling('365D').sum() # 恢复原索引结构 return group_sorted.reset_index() # 分组应用函数并整理结果 df_result = df.groupby('customer').apply(compute_rolling_sum).reset_index(drop=True)
验证结果
运行后得到的结果与你期望的输出完全一致,部分示例如下:
| date | customer | daily_total_per_customer | rolling_total |
|---|---|---|---|
| 2016-07-29 | 1 | 100 | 100.0 |
| 2016-08-01 | 1 | 50 | 150.0 |
| 2017-01-12 | 1 | 80 | 230.0 |
| 2017-10-23 | 1 | 180 | 260.0 |
关键注意点
- 必须确保
date列是datetime类型,否则Pandas无法解析时间间隔(如365D)。 - 一定要按
customer分组,否则会计算全局的滚动和,混淆不同客户的数据。 - 计算前需按客户和日期排序,保证滚动窗口是按时间顺序累加的。
内容的提问来源于stack exchange,提问作者jack93g
相关产品推荐
相关产品推荐

