滑动窗口操作的Numpy矢量化

滑动窗口操作的Numpy矢量化

本文介绍了滑动窗口操作的Numpy矢量化的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有以下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_25 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.

任何帮助将不胜感激.

推荐答案

我们可以使用 NumPy broadcasting 以矢量化方式创建那些滑动窗口索引.然后,我们可以简单地用它们索引到arr_2中,以创建一个3D数组,并与2D数组arr_1进行逐元素乘法,这又将再次打开broadcasting.

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矢量化的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-11 16:02