如何使用pandas实现按天对齐的N日滚动窗口统计而非逐行滚动计算
按天对齐滚动窗口的高效实现方案
核心思路
通过「按天聚合计算+结果回灌」的方式实现需求,全程使用pandas原生向量化操作,性能远高于自定义循环:
- 仅提取每天的最后一条记录计算滚动窗口统计值,得到每日正确的统计结果
- 将每日的计算结果映射回当天的所有行,实现同天所有行复用相同统计值
实现代码
import pandas as pd # 你的测试数据 l1=[1,2,3,4,5,6,7,8,9,10,11,12] ts=[pd.Timestamp('2017-01-01'), pd.Timestamp('2017-01-02'), pd.Timestamp('2017-01-03'), pd.Timestamp('2017-01-04'), pd.Timestamp('2017-01-05'), pd.Timestamp('2017-01-05'), pd.Timestamp('2017-01-05'), pd.Timestamp('2017-01-06'), pd.Timestamp('2017-01-06'), pd.Timestamp('2017-01-07'), pd.Timestamp('2017-01-07'), pd.Timestamp('2017-01-08')] df = pd.DataFrame({'t':ts, 'c':l1, 'm':l1, 's':l1}).set_index('t') # 核心处理逻辑 # 1. 新增日期列用于按天分组 df['date'] = df.index.date # 2. 提取每天最后一条记录计算滚动统计值 daily_last = df.groupby('date').tail(1) daily_rolling = daily_last.rolling('3D').agg({'c':'count', 'm':'mean', 's':'std'}) # 3. 构造日期到统计值的映射 date_map = daily_rolling.set_index(daily_rolling.index.date).to_dict('index') # 4. 结果回灌到原表所有行 df[['c','m','s']] = df['date'].map(date_map).apply(pd.Series) # 输出结果(删除辅助列) res = df.drop('date', axis=1) print(res)
性能说明
该方案的计算量仅和数据覆盖的天数正相关,和单日的记录条数无关,就算单天有十万级以上的记录,也不会增加额外计算开销,完全可以处理大规模数据集。
注意事项
执行前请确保DataFrame的时间索引为升序排列,若未排序可先执行df = df.sort_index()预处理。
内容的提问来源于stack exchange,提问作者John C.
相关产品推荐
相关产品推荐

