功能说明
加权窗口指在窗口计算中为窗口内的不同数据点分配不同的权重。pandas 提供了两种主要实现方式:
rolling(win_type=...)—— 固定窗口内的加权统计ewm()—— 全历史指数衰减加权加权窗口常用于平滑时间序列、突出近期数据的影响、降低极端值的影响。
rolling(win_type=...) 加权滚动窗口
核心用法
在
rolling()中指定win_type参数,使用 SciPy 中的窗口函数为窗口内数据加权。DataFrame.rolling(window, win_type='triang').mean()
支持的窗口类型
| 窗口类型 | 说明 | 典型用途 |
|---|---|---|
boxcar | 矩形窗(等权) | 等同无加权滚动 |
triang | 三角窗(中心权重最高) | 平滑去噪 |
blackman | Blackman 窗(旁瓣抑制好) | 频谱分析 |
hamming | Hamming 窗 | 信号处理 |
bartlett | Bartlett 窗(三角窗变体) | 平滑 |
parzen | Parzen 窗 | 核密度估计 |
bohman | Bohman 窗 | 信号处理 |
blackmanharris | Blackman-Harris 窗(动态范围大) | 高精度频谱 |
nuttall | Nuttall 窗 | 频谱分析 |
barthann | Bartlett-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)