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

问题描述 投票:0回答:1

人们很友好地解释: 如何使用numpy计算向量滚动窗口的相关系数? 有了这个 answer 我在哪里捡到的:

f_PH_numpy 是我的方法,它使用 sliding_window_view 和 用于逐行计算向量相关性的向量化函数 系数

我现在正尝试使用带有 numba 的 GPU 来解决同样的问题。不幸的是,添加

import numba as nb
from numba import jit, njit, prange, jit_module
@njit(fastmath=True, cache=True, parallel=True)

上面的代码导致我无法解决的错误(我不够好),例如:

TypingError: Unknown attribute 'sliding_window_view' of type Module(<module 'numpy.lib.stride_tricks' from 'C:\\Users\\didie\\miniconda3\\envs\\spyder-cf\\lib\\site-packages\\numpy\\lib\\stride_tricks.py'>)

关于如何使用 numba(或 GPU 的等效代码)代码获得解决方案的任何(其他)想法?

编辑:根据要求,我运行的代码(数据是一个浮点系列):

# v is a 1-D array that stores all correlation coef.
max_l = int(serie_o.shape[0] * 0.5)  # max_l is half the serie_o size
for l in range(3, max_l, 1):
   v = np.zeros(serie_o.shape[0]).astype('float32')
   y = np.arange(l)  # sequential sequence for the correlation
   ym = y - np.mean(y)
   swindow = np.lib.stride_tricks.sliding_window_view(serie_o.copy(), (l,))  # all sub-series to be correlated
   # https://stackoverflow.com/questions/75072435/how-to-create-a-rolling-correlation-using-only-numpy-from-a-1d-array#75072873
   xm = swindow - np.mean(swindow, axis=1, keepdims=True)
   xm[xm == 0] = np.nan  # to avoid any potential division by 0
   v[-(serie_o.shape[0] - l + 1):] =  np.roll(np.sum(xm * ym, axis=1) / np.sqrt(np.sum(xm**2, axis=1) * np.sum(ym**2)), 1)  # tous les coefficients de corrélation

编辑:我尝试开发的代码(x 在这里是为了计时):

    # v is a 1-D array that stores all correlation coef.
    @njit(fastmath=True, cache=True, parallel=True)
    def vecteur_correlation_46(s, max_l):
        for l in range(3, max_l, 1):
           v = np.zeros(s.shape[0]).astype('float32')
           y = np.arange(l)  # sequential sequence for the correlation
           ym = y - np.mean(y)
           swindow = np.lib.stride_tricks.sliding_window_view(s.copy(), (l,))  # all sub-series to be correlated
           xm = x - np.mean(x, axis=1, keepdims=True)
           xm[xm == 0] = np.nan  # to avoid any potential division by 0
           correl =  np.sum(xm * ym, axis=1) / np.sqrt(np.sum(xm**2, axis=1) * np.sum(ym**2))
           v[-(s.shape[0] - l + 1):] =  np.roll(correl, 1)

# start
max_l = int(serie_o.shape[0] * 0.5)  # max_l is half the serie_o size
x = 1000
for i in range(x):
    b = vecteur_correlation_46(data, max_l)
python gpu correlation numba sliding
1个回答
0
投票

np.lib.stride_tricks.sliding_window_view
不受 Numba 支持,但这很好。实际上,在这里使用 stride_tricks 效率不高,因为使用它会导致创建读取/填充速度较慢的大型临时数组。与现代 CPU 内核的计算能力相比,主内存速度较慢。相反,你应该保留你最初的基于循环的代码。这对 Numba 很好,实际上使用循环通常更快,特别是如果你避免在其中进行分配。

此外,

parallel=True
可能不是一个好主意,因为它只能并行化每个 Numpy 调用(它不能自动并行化顺序循环)。问题是只有当数组非常大时才值得这样做,因为为许多线程提供工作并等待它们会引入大量开销。

此外,Numba 默认不使用 GPU。它不能透明地在 GPU 上运行基于 CPU 的代码。这根本不可能(有效地)做到,因为 GPU 和 CPU 的运行方式非常不同。如果你只是想毫不费力地将 CPU Numpy 代码转换为 GPU Numpy 代码,那么 CuPy 无疑是更好的选择。事实证明,Cupy 显然支持

np.lib.stride_tricks.sliding_window_view
.

© www.soinside.com 2019 - 2024. All rights reserved.