功能说明

加权窗口指在窗口计算中为窗口内的不同数据点分配不同的权重。pandas 提供了两种主要实现方式:

  1. rolling(win_type=...) —— 固定窗口内的加权统计
  2. ewm() —— 全历史指数衰减加权

加权窗口常用于平滑时间序列、突出近期数据的影响、降低极端值的影响。

rolling(win_type=...) 加权滚动窗口

核心用法

在 rolling() 中指定 win_type 参数,使用 SciPy 中的窗口函数为窗口内数据加权。

DataFrame.rolling(window, win_type='triang').mean()

支持的窗口类型

窗口类型说明典型用途
boxcar矩形窗(等权)等同无加权滚动
triang三角窗(中心权重最高)平滑去噪
blackmanBlackman 窗(旁瓣抑制好)频谱分析
hammingHamming 窗信号处理
bartlettBartlett 窗(三角窗变体)平滑
parzenParzen 窗核密度估计
bohmanBohman 窗信号处理
blackmanharrisBlackman-Harris 窗(动态范围大)高精度频谱
nuttallNuttall 窗频谱分析
barthannBartlett-Hann 窗折衷平滑
cosine余弦窗信号处理
exponential指数窗(需 tau 参数)强调近期数据
gaussian高斯窗(需 std 参数)高斯平滑

使用示例

import pandas as pd
import numpy as np
 
s = pd.Series(np.random.randn(100).cumsum())
 
# 三角加权移动平均
s.rolling(10, win_type='triang').mean()
 
# 高斯加权(需指定 std)
s.rolling(10, win_type='gaussian').mean(std=2.0)
 
# 指数窗(需指定 tau)
s.rolling(10, win_type='exponential').mean(tau=5)
 
# 汉明窗
s.rolling(10, win_type='hamming').mean()

使用限制

  • 使用 win_type 时不能调用 agg() 等复杂聚合,通常只支持 mean()、sum()、std()、var() 等
  • 某些窗口类型需要额外的关键字参数传递到窗口函数中(如 gaussian → std,exponential → tau)
  • 不支持 apply() 自定义函数

ewm() 指数加权窗口

核心用法

ewm() 是另一种加权窗口,权重随数据点距当前时间的距离指数衰减,所有历史数据参与计算。

DataFrame.ewm(com=None, span=None, halflife=None, alpha=None).mean()

权重参数对照

参数权重公式适用场景
alpha直接指定 最直观,直接控制新数据权重
com统计应用中常见
span类比 N 期移动平均,最常用
halflife直观表达权重减半的时间

指数加权示例

# 四种方式近似等价(span 20 ≈ com 9.5 ≈ halflife 13.9 ≈ alpha 0.095)
s.ewm(span=20).mean()
s.ewm(com=9.5).mean()
s.ewm(halflife=13.9).mean()
s.ewm(alpha=0.095).mean()

rolling(win_type=...) vs ewm() 对比

对比维度rolling(win_type=...)ewm()
窗口范围固定大小窗口从起点到当前的全部数据
权重方式窗口函数(三角、高斯等)指数衰减
历史数据窗口外数据不参与所有历史数据参与
权重分布对称或可自定义严格近期优先
计算复杂度O(n·window)O(n)
适用场景平滑、信号处理金融时序、实时预测

🎯 实际应用场景

金融技术指标 — 布林带

# 布林带 = 20日移动均值 ± 2倍滚动标准差
prices = pd.Series(np.random.randn(200).cumsum() + 100)
 
middle = prices.rolling(20).mean()
upper = middle + 2 * prices.rolling(20).std()
lower = middle - 2 * prices.rolling(20).std()

金融技术指标 — MACD

# MACD = EMA(12) - EMA(26)
prices = pd.Series(np.random.randn(200).cumsum() + 100)
 
ema_12 = prices.ewm(span=12, adjust=False).mean()
ema_26 = prices.ewm(span=26, adjust=False).mean()
macd = ema_12 - ema_26

信号平滑 — 高斯平滑

signal = pd.Series(np.random.randn(200) + np.sin(np.linspace(0, 10, 200)))
 
# 使用高斯加权窗口平滑信号
smoothed = signal.rolling(15, win_type='gaussian').mean(std=5)

🔗 相关链接