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

如何用Pandas计算客户过去365天的滚动累计值?

Pandas计算每个客户过去365天滚动累计值的解决方法

错误原因分析

你遇到的ValueError是因为:

  1. 你将date设置为多层索引(['customer', 'date'])的一部分,此时date不再是DataFrame的列,rolling的on='date'参数无法找到对应列。
  2. 代码没有按客户分组,全局计算滚动和会混淆不同客户的时间线,不符合“每个客户独立计算”的需求。

正确实现方法

步骤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)

验证结果

运行后得到的结果与你期望的输出完全一致,部分示例如下:

datecustomerdaily_total_per_customerrolling_total
2016-07-291100100.0
2016-08-01150150.0
2017-01-12180230.0
2017-10-231180260.0

关键注意点

  • 必须确保date列是datetime类型,否则Pandas无法解析时间间隔(如365D)。
  • 一定要按customer分组,否则会计算全局的滚动和,混淆不同客户的数据。
  • 计算前需按客户和日期排序,保证滚动窗口是按时间顺序累加的。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.24 14:09:07