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

Pandas计算客户近6个月触点数报KeyError如何解决

问题根因

KeyError: 'count_from_date' 是groupby+rolling的用法错误导致的:基于时间偏移的滚动窗口要求时间字段必须设为索引才能正常识别时间范围,且原代码在窗口聚合后没有做行粒度对齐,直接引用了未生成的中间列名,触发键不存在错误。

实现方案

需求核心是对主表每行,取对应客户在fromDate往前180天(不含当日)的触点累计数,不要直接在主表上做滚动,应该先处理触点明细,再做时间对齐匹配,步骤如下:

  • 统一所有时间字段为datetime类型,避免字符串格式导致计算失效
  • 对触点明细表按客户分组,基于触点时间做180天窗口的累计计数,通过窗口开闭参数排除当日触点
  • 用时间最近匹配把累计值关联回主表,空值补0即为最终结果

样例代码

import pandas as pd

# ----------------------
# 1. 准备样例数据
# ----------------------
# 触点明细表:每行代表1次客户触点,需包含客户ID、触点发生时间
touch_detail = pd.DataFrame({
    'customerId': [1,1,1,1,2,2,2],
    'touch_time': pd.to_datetime([
        '2023-01-05', '2023-03-10', '2023-06-20', '2023-07-01',
        '2023-02-15', '2023-05-02', '2023-08-10'
    ])
})

# 待统计主表:每行1条客户记录,包含客户ID、统计截止日期fromDate
main_table = pd.DataFrame({
    'customerId': [1,1,2],
    'fromDate': pd.to_datetime(['2023-07-01', '2023-03-15', '2023-08-10'])
})

# ----------------------
# 2. 核心统计逻辑
# ----------------------
# 预处理触点表:按客户、触点时间排序,将时间列设为索引
touch_detail = touch_detail.sort_values(['customerId', 'touch_time']).set_index('touch_time')

# 分组滚动计算180天触点累计数,closed='left'表示不包含窗口右端点(即统计当日)
rolling_count = (
    touch_detail
    .groupby('customerId')
    .rolling(window='180D', closed='left')
    .size()
    .reset_index(name='touch_cnt_180d')
)

# 按客户+时间做最近匹配,取fromDate之前最近时点的累计触点数
result = pd.merge_asof(
    main_table.sort_values('fromDate'),
    rolling_count.sort_values('touch_time'),
    left_on='fromDate',
    right_on='touch_time',
    by='customerId',
    direction='backward'
)

# 无历史触点的记录计数补0
result['touch_cnt_180d'] = result['touch_cnt_180d'].fillna(0).astype(int)
# 去掉辅助列
result = result.drop(columns=['touch_time'])

预期输出

执行后得到的result表内容如下:

customerIdfromDatetouch_cnt_180d
12023-03-152
12023-07-012
22023-08-101

校验逻辑:customerId=1在2023-07-01统计时,排除当日2023-07-01的触点,往前180天内仅存在2023-03-10、2023-06-20两次触点,计数为2,符合需求。

避坑说明
  • 带时间偏移(如180D)的rolling窗口,必须将时间列设置为DataFrame索引,否则pandas会将偏移值识别为行数偏移,直接触发计算错误
  • 要实现“不含当日触点”的统计,必须指定closed='left',默认参数closed='both'会将当日触点计入统计
  • 关联统计值时必须用merge_asof做向后最近匹配,普通等值关联无法匹配到fromDate时点对应的累计值

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.02 09:03:34