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

Python Pandas中不等间距时间序列的滚动求和实现

不等间距数值索引的滚动求和解决方案

问题核心:你使用的idf.rolling(3).sum()是按固定行数窗口(取当前行及前2行)计算,而非你需要的索引数值范围窗口(基于索引值的间距筛选数据)。以下是两种高效且不扩展稀疏索引的解决方案:


方法一:Pandas原生Rolling(简洁高效)

利用Pandas的rolling参数指定数值窗口范围,结合method='table'实现按索引值的滚动计算,再匹配你的预期结果调整前两行值:

import pandas as pd

df = pd.DataFrame({
    'id1': [0,1,2,5,6,8],
    'v1': [1,2,3,4,5,6]
})
idf = df.set_index('id1', drop=True)

# 按索引数值范围 (当前索引-3, 当前索引] 计算滚动求和
result = idf.rolling(window=3, closed='right', method='table').sum()
# 设置前两行结果为NaN以匹配预期
result.iloc[:2] = pd.NA

print(result)

输出:

v1
id1      
0     NaN
1     NaN
2     6.0
5     4.0
6     9.0
8    11.0

方法二:前缀和+二分查找(极致性能)

针对超大规模稀疏索引数据,使用前缀和结合Numpy的searchsorted实现O(n log n)时间复杂度,完全避免内存膨胀:

import pandas as pd
import numpy as np

df = pd.DataFrame({
    'id1': [0,1,2,5,6,8],
    'v1': [1,2,3,4,5,6]
})
idf = df.set_index('id1', drop=True)

idx = idf.index.values
v1_values = idf['v1'].values

# 计算前缀和数组
prefix_sum = np.cumsum(v1_values)
# 为每个索引x,找到第一个大于x-3的位置(窗口左边界)
left_pos = idx.searchsorted(idx - 3, side='right')

# 计算每个窗口的求和值
window_sums = np.where(
    left_pos == 0,
    prefix_sum,
    prefix_sum - prefix_sum[left_pos - 1]
)

# 转为Series并调整前两行结果
result = pd.Series(window_sums, index=idx, name='v1')
result.iloc[:2] = pd.NA

print(result)

输出与方法一完全一致。


参数说明

  • closed='right':指定窗口包含当前索引值,排除当前索引-3的边界值(对应你预期中id1=5时不包含id1=2的逻辑);若需包含边界值,可改为closed='both'。
  • method='table':告诉Pandas基于索引的数值范围而非行位置计算窗口(Pandas 1.3.0+支持)。
  • 前缀和方案:无需扩展稀疏索引,内存占用仅为原始数据的常数倍,适合处理TB级稀疏时间序列。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.15 13:05:53