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

一段代码:

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+1 到 i+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. 物理意义 :衡量"最近的波动能量",是检测变化点 和异常的利器
相关推荐
xfan_me10 分钟前
维修保养记录精准版 API 对接实战指南
java·大数据·python
海上小飞龙13 分钟前
改一个数,右边全得重算,这题怎么扛住两万次查询
java·c++·python
阿里嘎多学长18 分钟前
2026-09-28 GitHub 热点项目精选
开发语言·程序员·github·代码托管
XiaoMaqqqq36 分钟前
目前知名的IP驱动产业新场景新工具有哪些
网络·python·网络协议·tcp/ip
玩大数据的龙威43 分钟前
农经权二轮延包—固定比例尺不定图幅的公示图批量生成
python·arcgis·二轮延包公示图
程序猿编码1 小时前
C++/CUDA 手写 LLM 推理引擎:拆解 vLLM 核心 PagedAttention 与连续批处理
开发语言·c++·深度学习·神经网络·推理·vllm
hold?fish:palm1 小时前
44 二叉搜索树中第K小的元素
开发语言·c++·算法
凉茶钱1 小时前
【吃透C++】万字解析类和对象
开发语言·c++
白杨尚青2 小时前
C++入门篇(十):string(上)——认识string:构造与三大遍历(一条龙讲透operator[]、迭代器、auto、范围for)
java·开发语言·c++·笔记·stl
可乐鸡翅yeah_2 小时前
hls.js 切换多个视频源,新手开发常见踩坑
开发语言·前端·javascript·ios·ffmpeg·音视频·safari