Python 数据向量列表的快速滚动求和(2d矩阵)
我正在寻找一种快速计算滚动和的方法,可能使用Numpy。以下是我的第一个方法:Python 数据向量列表的快速滚动求和(2d矩阵),python,numpy,sliding-window,Python,Numpy,Sliding Window,我正在寻找一种快速计算滚动和的方法,可能使用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.,
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的答案: 输出
[[ 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
由于运行总和==移动平均值,可能重复:除除法部分外,但除此之外,是的。您不取实际总和。你们在寻找一个滑动窗口,而不是一个连续的总和。我认为滑动窗口本身也不正确。我想你可以在滑动窗口(或滚动窗口)上求和,或者在滑动窗口上求平均值。我建议将其编辑为滚动总和,这似乎更接近正确的事情。我同意E先生的意见。快速滚动总和是我的想法。抱歉搞混了,太棒了。只是吹毛求疵,你必须取实际的
sum(运行\u sum(M))
你确定吗?我不是从这个问题上明白的。?在这种情况下,OP是在寻找一个滑动窗口,而不是一个正在运行的SUM是的,我认为你是对的,因为措辞不正确。但是很清楚问题的输出应该是什么。修复了标题和标签
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