统计_滚动标准差:局部波动性衡量

一段代码:

python 复制代码
y = np.concatenate([
    np.random.normal(0, 0.5, 100),   # 低波动
    np.random.normal(0, 3.0, 50),    # 高波动
    np.random.normal(0, 0.5, 100)    # 低波动
])
window = 20
rolling_std = np.array([np.std(y[max(0,i-window+1):i+1]) for i in range(len(y))])
plt.figure(figsize=(10, 4))
plt.plot(rolling_std, color='orange')
plt.title('Rolling std dev')
plt.xlabel('index')
plt.ylabel('std')

这段代码实现的是滚动标准差 (Rolling Standard Deviation),也叫移动标准差 。让我详细解释它的原理和物理含义:

补充:方差 标准差计算公式

代码解析

python 复制代码
window = 20
rolling_std = np.array([np.std(y[max(0,i-window+1):i+1]) for i in range(len(y))])

核心逻辑 :对于每个位置 i,计算过去 window 个数据点的标准差:

  • i < window-1 时(数据不足20个):

    • 切片从 0 开始,只取 i+1 个数据
    • 这是部分窗口(前向填充)
  • i >= window-1 时:

    • 切片从 i-window+1i+1,正好 window 个数据
    • 这是完整窗口

物理含义

1. 波动性的动态监测

滚动标准差衡量的是局部波动性,而不是整体波动:

  • 低滚动标准差:最近的数据点都很接近均值 → 市场平稳/信号稳定
  • 高滚动标准差:最近的数据点剧烈波动 → 市场动荡/信号变化剧烈

2. 实际应用场景

领域 应用
金融 波动率计算(如 Bollinger Bands)、风险管理
信号处理 检测信号突变点、噪声水平估计
质量控制 监测生产过程的稳定性
气象学 温度/气压的短期波动分析

3. 与整体标准差的对比

python 复制代码
# 整体标准差(全局视角)
global_std = np.std(y)  # 一个值,描述整体波动

# 滚动标准差(局部视角)
rolling_std = [...]     # 一系列值,描述波动随时间的变化

例子

  • 整体标准差可能很大(因为包含所有波动)
  • 但滚动标准差可以告诉你:什么时候波动大,什么时候波动小

改进建议

1. 正确处理边界(避免部分窗口混淆)

python 复制代码
window = 20
rolling_std = np.array([
    np.std(y[i-window+1:i+1]) if i >= window-1 else np.nan 
    for i in range(len(y))
])

nan 代替前几个不完整的窗口,更清晰。

2. 使用 Pandas(更高效、更简洁)

python 复制代码
import pandas as pd

rolling_std = pd.Series(y).rolling(window=20).std().values

Pandas 默认 ddof=1(样本标准差),如需总体标准差:

python 复制代码
rolling_std = pd.Series(y).rolling(window=20).std(ddof=0).values

3. NumPy 向量化版本(更快)

python 复制代码
def rolling_std_numpy(y, window):
    # 使用卷积或 cumsum 实现,比列表推导快很多
    cumsum = np.cumsum(y)
    cumsum_sq = np.cumsum(np.square(y))
    
    # 计算窗口和
    sum_win = cumsum[window-1:] - np.append([0], cumsum[:-window])
    sum_sq_win = cumsum_sq[window-1:] - np.append([0], cumsum_sq[:-window])
    
    # 计算均值和方差
    mean_win = sum_win / window
    var_win = sum_sq_win / window - mean_win**2
    
    # 添加 NaN 填充前 window-1 个位置
    return np.concatenate([np.full(window-1, np.nan), np.sqrt(var_win)])

可视化示例

python 复制代码
import numpy as np
import matplotlib.pyplot as plt

# 生成数据:平稳 + 高波动 + 平稳
np.random.seed(42)
y = np.concatenate([
    np.random.normal(0, 0.5, 100),   # 低波动
    np.random.normal(0, 3.0, 50),    # 高波动
    np.random.normal(0, 0.5, 100)    # 低波动
])

window = 20
rolling_std = pd.Series(y).rolling(window).std()

plt.figure(figsize=(12, 6))
plt.subplot(2,1,1)
plt.plot(y, alpha=0.7)
plt.title('原始数据')
plt.ylabel('值')
plt.grid(True)

plt.subplot(2,1,2)
plt.plot(rolling_std, color='orange')
plt.axhline(y=np.std(y), color='red', linestyle='--', label=f'全局标准差 = {np.std(y):.2f}')
plt.title('滚动标准差 (window=20)')
plt.xlabel('索引')
plt.ylabel('标准差')
plt.legend()
plt.grid(True)

plt.tight_layout()
plt.show()

输出效果

  • 前100个点:滚动标准差 ~0.5
  • 中间50个点:滚动标准差 ~3.0(明显升高,捕捉到波动增加)
  • 后100个点:滚动标准差 ~0.5(回降,检测到波动减小)

关键要点

  1. 滚动标准差 ≠ 整体标准差 :它是时变的,能捕捉局部波动特征
  2. 窗口大小影响灵敏度
    • 小窗口(如 5):反应快,但噪声多
    • 大窗口(如 50):反应慢,但更平滑
  3. 物理意义 :衡量"最近的波动能量",是检测变化点异常的利器
相关推荐
星越华夏9 小时前
YOLO v11蚊子数据集训练
人工智能·python·深度学习·yolo
这个DBA有点耶9 小时前
数据库管理工具+开发工具的融合:AI如何重塑DBA工作流?
开发语言·数据库·人工智能·sql·云计算·dba
lynnlovemin9 小时前
【信息学竞赛专题】滑动窗口(尺取法)超全详解|C++模板+经典例题+避坑指南
开发语言·c++·算法·滑动窗口·信息学竞赛
wjs20249 小时前
JavaScript 类型转换
开发语言
似水এ᭄往昔9 小时前
【Qt】--Qt概述
开发语言·c++·qt
星秀日9 小时前
rust学习入门
开发语言·学习·rust
奔跑的Ma~9 小时前
企业级 Codex 部署与团队协作方案
后端·python·ai编程·codex·ai学习
星越华夏10 小时前
python办公自动化,csv文件/excel文件差集合并
开发语言·python·excel
jiayong2310 小时前
03 写第一个带逐行注释的 Python 程序
python