滑动窗口操作的Numpy矢量化 [英] Numpy Vectorization of sliding-window operation
问题描述
我有以下numpy数组:
I have the following numpy arrays:
arr_1 = [[1,2],[3,4],[5,6]] # 3 X 2
arr_2 = [[0.5,0.6],[0.7,0.8],[0.9,1.0],[1.1,1.2],[1.3,1.4]] # 5 X 2
arr_1
显然是3 X 2
数组,而arr_2
是5 X 2
数组.
arr_1
is clearly a 3 X 2
array, whereas arr_2
is a 5 X 2
array.
现在不进行循环了,我想逐个元素地将arr_1和arr_2相乘,以便将滑动窗口技术(窗口大小3)应用于arr_2.
Now without looping, I want to element-wise multiply arr_1 and arr_2 so that I apply a sliding window technique (window size 3) to arr_2.
Example:
Multiplication 1: np.multiply(arr_1,arr_2[:3,:])
Multiplication 2: np.multiply(arr_1,arr_2[1:4,:])
Multiplication 3: np.multiply(arr_1,arr_2[2:5,:])
我想以某种矩阵乘法形式执行此操作,以使其比当前形式的当前解决方案更快:
I want to do this in some sort of a matrix multiplication form to make it faster than my current solution which is of the form:
for i in (2):
np.multiply(arr_1,arr_2[i:i+3,:])
因此,如果arr_2中的行数很大(数以万计),则此解决方案的伸缩性不是很好.
So if the number of rows in arr_2 are large (of the order of tens of thousands), this solution doesn't really scale very well.
任何帮助将不胜感激.
推荐答案
We can use NumPy broadcasting
to create those sliding windowed indices in a vectorized manner. Then, we can simply index into arr_2
with those to create a 3D
array and perform element-wise multiplication with 2D
array arr_1
, which in turn will bring on broadcasting
again.
所以,我们将有一个像这样的矢量化实现-
So, we would have a vectorized implementation like so -
W = arr_1.shape[0] # Window size
idx = np.arange(arr_2.shape[0]-W+1)[:,None] + np.arange(W)
out = arr_1*arr_2[idx]
运行时测试并验证结果-
Runtime test and verify results -
In [143]: # Input arrays
...: arr_1 = np.random.rand(3,2)
...: arr_2 = np.random.rand(10000,2)
...:
...: def org_app(arr_1,arr_2):
...: W = arr_1.shape[0] # Window size
...: L = arr_2.shape[0]-W+1
...: out = np.empty((L,W,arr_1.shape[1]))
...: for i in range(L):
...: out[i] = np.multiply(arr_1,arr_2[i:i+W,:])
...: return out
...:
...: def vectorized_app(arr_1,arr_2):
...: W = arr_1.shape[0] # Window size
...: idx = np.arange(arr_2.shape[0]-W+1)[:,None] + np.arange(W)
...: return arr_1*arr_2[idx]
...:
In [144]: np.allclose(org_app(arr_1,arr_2),vectorized_app(arr_1,arr_2))
Out[144]: True
In [145]: %timeit org_app(arr_1,arr_2)
10 loops, best of 3: 47.3 ms per loop
In [146]: %timeit vectorized_app(arr_1,arr_2)
1000 loops, best of 3: 1.21 ms per loop
这篇关于滑动窗口操作的Numpy矢量化的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!