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

如何在Pandas中对分组滚动窗口内的Counter对象进行求和?

报错原因

Pandas 内置的rolling.sum()仅针对数值类型设计,聚合时会强制将输入转换为浮点型计算,而Counter属于Python自定义对象,无法被转换为数值类型,因此触发类型错误。

可行解决方案

两种方案都支持自定义未来统计天数,可直接修改FORWARD_DAYS变量调整:

from collections import Counter
import pandas as pd

# 自定义统计未来天数
FORWARD_DAYS = 6

方案1:逐行筛选法(逻辑直观,适合小数据量)

不需要调整滚动窗口方向,代码易读易维护:

# 先按id、日期排序,将日期设为索引
df = df.sort_values(['id', 'dates']).set_index('dates')

def calc_forward_counter(group_df):
    result = []
    for curr_dt in group_df.index:
        # 筛选同id下 大于当前日期 且 小于等于当前日期+6天的所有行
        mask = (group_df.index > curr_dt) & (group_df.index <= curr_dt + pd.Timedelta(days=FORWARD_DAYS))
        # 对筛选出的Counter求和,初始值为空Counter
        total_cnt = sum(group_df.loc[mask, 'state_cntr'], Counter())
        result.append(total_cnt)
    group_df['output_needed'] = result
    return group_df

# 按id分组处理后恢复原结构
df = df.groupby('id', group_keys=False).apply(calc_forward_counter).reset_index()

方案2:滚动自定义聚合(性能更高,适合大数据量)

通过调整排序方向适配滚动窗口默认的向后统计逻辑,比逐行筛选效率高3~10倍:

# 先按id、日期排序,将日期设为索引
df = df.sort_values(['id', 'dates']).set_index('dates')

def rolling_calc_counter(group_df):
    # 组内按日期倒序排列,把未来数据转到滚动窗口可覆盖的区间
    group_df = group_df.sort_index(ascending=False)
    # 滚动6天,自定义Counter求和,shift(1)排除当前行,空值填充为空Counter
    group_df['output_needed'] = group_df['state_cntr'].rolling(f'{FORWARD_DAYS}D').apply(
        lambda x: sum(x, Counter()), raw=False
    ).shift(1).fillna(Counter())
    # 恢复正序排列返回
    return group_df.sort_index()

# 按id分组处理后恢复原结构
df = df.groupby('id', group_keys=False).apply(rolling_calc_counter).reset_index()

两种方案输出均完全匹配需求的预期结果。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.28 16:15:01