You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

如何使用Numpy计算向量滚动窗口的相关系数

如何使用Numpy计算向量滚动窗口的相关系数

嘿,我完全理解你想要摆脱循环、用更高效的Numpy向量化操作来计算滚动窗口相关系数的需求——循环不仅写起来麻烦,在数据量较大时效率也会差很多。咱们可以通过拆解相关系数的计算公式,结合Numpy的滑动窗口工具来实现无循环的解决方案!

首先,先回顾一下相关系数的本质:两个变量的协方差除以它们各自标准差的乘积。因为你是和固定的数组[0,1,2,3,4]计算相关系数,这个固定数组的均值和标准差是可以提前一次性算好的,不用重复计算,这能省不少功夫。

具体实现步骤

  1. 提前计算固定数组的统计量
    我们要对比的固定数组是y = np.arange(5),先算出它的均值和总体标准差(和np.corrcoef保持一致,用ddof=0):

    import numpy as np
    
    data = np.array([10,5,8,9,15,22,26,11,15,16,18,7,4,8,-2,-3,-4,-6,-2,0,10,0,5,8])
    length = 5
    y = np.arange(length)
    y_mean = y.mean()
    y_std = y.std(ddof=0)  # 对应np.corrcoef的总体标准差计算方式
    
  2. 生成所有滚动窗口的数据集
    使用Numpy的np.lib.stride_tricks.sliding_window_view(Numpy 1.20+支持)可以快速生成所有长度为5的滚动窗口,然后我们截取和你循环逻辑对应的窗口(前19个,对应原循环中i从5到23的情况):

    # 生成所有滚动窗口,形状为(20,5),截取前19个匹配原循环逻辑
    window_data = np.lib.stride_tricks.sliding_window_view(data, length)[:-1]
    

    如果你的Numpy版本较低,没有sliding_window_view,可以用手动 stride 实现的滚动窗口函数替代:

    def rolling_window(arr, window_size):
        shape = arr.shape[:-1] + (arr.shape[-1] - window_size + 1, window_size)
        strides = arr.strides + (arr.strides[-1],)
        return np.lib.stride_tricks.as_strided(arr, shape=shape, strides=strides)
    
    window_data = rolling_window(data, length)[:-1]
    
  3. 批量计算每个窗口的统计量和相关系数
    用向量化操作批量计算每个窗口的均值、标准差,以及和y的协方差,最后算出相关系数:

    # 每个窗口的均值和总体标准差
    window_means = window_data.mean(axis=1)
    window_stds = window_data.std(axis=1, ddof=0)
    
    # 计算每个窗口与y的协方差
    cov = np.mean((window_data - window_means[:, np.newaxis]) * (y - y_mean), axis=1)
    
    # 计算相关系数
    r = cov / (window_stds * y_std)
    
  4. 构造最终结果数组
    和你的原代码一样,前5个元素填充0,后面填充计算出的相关系数:

    x = np.zeros_like(data, dtype='float32')
    x[length:] = r
    

验证结果

运行上面的代码后,你得到的x数组和原循环代码输出的结果完全一致:

[ 0.     0.     0.     0.     0.     0.607  0.959  0.98   0.328 -0.287
 -0.61  -0.314 -0.18  -0.8   -0.782 -0.847 -0.811 -0.825 -0.869 -0.283
 0.566  0.863  0.643  0.454]

这种方法完全利用了Numpy的向量化优势,比循环快得多,尤其是当你的数据量很大的时候效果会更明显!

备注:内容来源于stack exchange,提问作者tibibou

火山引擎 最新活动