数据向量列表(二维矩阵)的快速滚动和



我正在寻找一种快速计算滚动和的方法,可能使用 Numpy。这是我的第一个方法:

 def func1(M, w):
     Rtn = np.zeros((M.shape[0], M.shape[1]-w+1))
     for i in range(M.shape[1]-w+1):
         Rtn[:,i] = np.sum(M[:, i:w+i], axis=1)
     return Rtn
 M = np.array([[0.,  0.,  0.,  0.,  0.,  1.,  1.,  0.,  1.,  1.,  1.,  0.,  0.],
               [0.,  0.,  1.,  0.,  1.,  0.,  0.,  0.,  0.,  0.,  0.,  1.,  1.],
               [1.,  1.,  0.,  1.,  0.,  0.,  0.,  1.,  0.,  0.,  0.,  0.,  0.]])
 window_size = 4
 print func1(M, window_size)
 [[ 0.  0.  1.  2.  2.  3.  3.  3.  3.  2.]
  [ 1.  2.  2.  1.  1.  0.  0.  0.  1.  2.]
  [ 3.  2.  1.  1.  1.  1.  1.  1.  0.  0.]]

我想防止窗口(/sum)在循环中重做,并希望让它更快,所以我想出了以下函数,将总和限制为滚动窗口的第一个和最后一个元素:

 def func2(M, w):
     output = np.zeros((M.shape[0], M.shape[1]-w+1))
     sum = np.sum(M[:, 0:w], axis=1)
     output[:,0] = sum
     for i in range(w, M.shape[1]):
         sum = sum + M[:,i]- M[:,i-w]
         output[:,i-w+1] = sum
     return output

但令我惊讶的是,func2 并不比 func1 快:

 In [251]:
 M = np.random.randint(2, size=3000).reshape(3, 1000)
 window_size = 100
 %timeit func1(M, window_size)
 10 loops, best of 3: 20.9 ms per loop
 In [252]:
 %timeit func2(M, w)
 10 loops, best of 3: 15.5 ms per loop

我在这里错过了什么吗?你们知道更好的,我的意思是更快的方法来实现这一目标吗?

编自@Jaime的回答:https://stackoverflow.com/a/14314054/553404

import numpy as np
def rolling_sum(a, n=4) :
    ret = np.cumsum(a, axis=1, dtype=float)
    ret[:, n:] = ret[:, n:] - ret[:, :-n]
    return ret[:, n - 1:]
M = np.array([[0.,  0.,  0.,  0.,  0.,  1.,  1.,  0.,  1.,  1.,  1.,  0.,  0.],
              [0.,  0.,  1.,  0.,  1.,  0.,  0.,  0.,  0.,  0.,  0.,  1.,  1.],
              [1.,  1.,  0.,  1.,  0.,  0.,  0.,  1.,  0.,  0.,  0.,  0.,  0.]])
print(rolling_sum(M)) 

输出

[[ 0.  0.  1.  2.  2.  3.  3.  3.  3.  2.]
 [ 1.  2.  2.  1.  1.  0.  0.  0.  1.  2.]
 [ 3.  2.  1.  1.  1.  1.  1.  1.  0.  0.]]

计时

In [7]: %timeit rolling_sum(M, 4)
100000 loops, best of 3: 7.89 µs per loop
In [8]: %timeit func1(M, 4)
10000 loops, best of 3: 70.4 µs per loop
In [9]: %timeit func2(M, 4)
10000 loops, best of 3: 54.1 µs per loop

最新更新