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

一段代码:

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. 物理意义 :衡量"最近的波动能量",是检测变化点异常的利器
相关推荐
颜x小42 分钟前
[C#] C++与c#语法对比
开发语言·c++·c#
databook43 分钟前
用方差阈值过滤掉“惰性特征”
python·机器学习·scikit-learn
Freak嵌入式44 分钟前
MCU 低功耗模式解析:时钟门控、电源门控、深度休眠
人工智能·python·单片机·嵌入式硬件·开源·依赖倒置原则·micropython
weixin_423652131 小时前
C#使用JObject
开发语言·c#
国科安芯1 小时前
FreeRTOS RISC-V 浮点上下文切换移植:在 IAR 工程中完整保存 FPU 寄存器
java·开发语言·单片机·嵌入式硬件·算法·系统架构·risc-v
weixin_BYSJ19872 小时前
springboot校园自习室管理小程序---附源码32142
java·javascript·spring boot·python·django·flask·php
用户8356290780512 小时前
使用 Python 在 PDF 中绘制线条、矩形和自定义图形
后端·python
霸道流氓气质2 小时前
Java中集成Smile 技术教程:从入门到工程实践
java·开发语言
wang_yb3 小时前
用方差阈值过滤掉“惰性特征”
python·ai·databook
威联通网络存储3 小时前
TS-h2490FU在钢铁热轧/冷轧板材表面缺陷在线视觉检测中的部署
人工智能·python·计算机视觉·视觉检测