4

X给定具有T行和列的矩阵k

T = 50
H = 10
k = 5 
X = np.arange(T).reshape(T,1)*np.ones((T,k))

如何X使用 lag 沿行轴执行滚动累积和H

Xcum = np.zeros((T-H,k))
for t in range(H,T):
    Xcum[t-H,:] = np.sum( X[t-H:t,:], axis=0 )

请注意,在广播/矢量化最佳实践下,最好避免跨步和卷积。

4

3 回答 3

3

听起来你想要以下内容:

import scipy.signal
scipy.signal.convolve2d(X, np.ones((H,1)), mode='valid')

这当然使用卷积,但如前所述,问题是卷积操作。广播将导致更慢/内存密集型算法。

于 2014-08-27T18:38:24.583 回答
1

您实际上缺少滚动总和的最后一行,这将是正确的输出:

Xcum = np.zeros((T-H+1, k))
for t in range(H, T+1):
    Xcum[t-H, :] = np.sum(X[t-H:t, :], axis=0)

如果您只需要使用 numpy 在任意轴上执行此操作,最简单的方法是np.cumsum沿该轴执行 a ,然后将结果计算为两个切片的差异。使用您的示例数组和轴:

temp = np.cumsum(X, axis=0)
Xcum = np.empty((T-H+1, k))
Xcum[0] = temp[H-1]
Xcum[1:] = temp[H:] - temp[:-H]

另一种选择是使用 pandas 及其rolling_sum函数,它显然可以在 2D 数组上工作,就像你需要的那样:

import pandas as pd
Xcum = pd.rolling_sum(X, 10)[9:] # first 9 entries are NaN
于 2014-08-27T21:54:37.773 回答
0

这是一个跨步的解决方案。我意识到这不是你想要的,但我想知道它是如何比较的。

def foo2(X):
    temp = np.lib.stride_tricks.as_strided(X, shape=(H,T-H+1,k), 
        strides=(k*8,)+X.strides))
    # return temp.sum(0)
    return np.einsum('ijk->jk', temp)

这次是 35 us,而 Jaime 的cumsum解决方案是 22 us。 einsum比 快一点sum(0)temp使用X的数据,因此没有内存损失。但更难理解。

于 2014-08-28T04:32:01.643 回答