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

如何计算Datetime索引DataFrame列排除末月的12个月滚动平均值

工作日Datetime索引DataFrame排除末尾1月数据的12月滚动均值高效实现

不要用enumerate逐行遍历,直接用pandas原生向量化接口实现,性能比循环高两个数量级,全程不需要写自定义循环函数。

核心实现逻辑

  • 先定位数据集最后一个时间点,计算出最后1个月的时间分界阈值
  • 把阈值之后(即最后1个月)的目标列值置为NaN,pandas滚动计算默认自动跳过空值,这部分数据不会参与运算
  • 传入时间类窗口参数调用rolling方法,适配工作日索引自动跳过非交易日,直接计算滚动均值即可

可直接运行的代码示例

import pandas as pd
import numpy as np

# ----------------------
# 这里替换成你自己的DataFrame即可,要求索引是已转成DatetimeIndex的工作日序列
# 测试用构造数据:2022-2024年的工作日序列
dates = pd.bdate_range(start='2022-01-01', end='2024-05-31')
df = pd.DataFrame({'target_col': np.random.randn(len(dates))}, index=dates)
# ----------------------

# 计算最后1个月的分界点
last_ts = df.index.max()
exclude_threshold = last_ts - pd.DateOffset(months=1)

# 标记最后1个月数据为空,不参与计算
calc_series = df['target_col'].where(df.index <= exclude_threshold)

# 计算12个月滚动平均
df['rolling_12m_avg'] = calc_series.rolling(
    window='365D',  # 12个月自然时间窗口,自动识别索引里的工作日、跳过非交易日
    min_periods=198,  # 可选:要求至少9个月有效交易日(按每月22个交易日估算)才输出结果,避免前期数据过少产生无意义值
    closed='left'  # 窗口仅包含当前时间点之前的数据,避免引入未来数据
).mean()

常见踩坑说明

之前用mask/where/自定义函数运行失败基本都是这两个原因:

  1. 调用rolling时传了固定整数作为窗口大小(比如rolling(252)),固定窗口按行数滚动,无法适配时间规则,遇到节假日、交易日数量波动就会对齐错误
  2. 自定义滚动函数走Python逐行调用逻辑,性能差还容易出现索引对齐问题,完全没必要用

场景拓展

如果你的需求不是排除整个数据集最后1个月的数据,而是每个时间点的滚动窗口都跳过最近1个月的数据(即窗口范围为当前点往前13个月到往前1个月),直接用时间偏移shift实现即可,不需要做全量mask:

# 按时间偏移把序列往前挪1个月,自动适配工作日索引、不会按行错位
shifted_series = df['target_col'].shift(freq=pd.DateOffset(months=1))
df['rolling_12m_skip_1m'] = shifted_series.rolling('365D', min_periods=198).mean()

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.26 22:48:25