人们很友好地解释: 如何使用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)
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
.