2014-08-27 18 views
4

鑑於矩陣XT行和列k如何沿矩陣軸執行滾動和?

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

沿着行與滯後H軸線如何執行的X滾動累積和?

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

通知,優選避免步幅和卷積,下廣播/矢量的最佳做法。

+0

你檢查過'np.cumsum()'嗎? – 2014-08-27 18:31:13

+0

是,找不到'滾動'部分的答案。 – pvstrln 2014-08-27 18:57:12

+0

爲什麼'braodcasting/vectorization'最佳實踐排除了罷工? – hpaulj 2014-08-27 21:53:24

回答

2

聽起來像是你想要的以下內容:

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

這當然採用卷積,但問題,如上所述,是卷積運算。廣播會導致更慢/內存密集型算法。

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,然後計算您的結果作爲兩個切片的差異。與樣品陣列和軸:

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

另一種選擇是使用大熊貓及其rolling_sum功能,克服一切困難顯然適用於二維數組就像你需要它:

import pandas as pd 
Xcum = pd.rolling_sum(X, 10)[9:] # first 9 entries are NaN 
+0

thx海梅,你懂了! – pvstrln 2014-08-30 11:11:25

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我們的解決方案。 einsumsum(0)快一點。 temp使用X的數據,所以不會造成內存損失。但它很難理解。

+1

對於大型窗戶,這將重做很多工作......當您將窗戶滑動一個位置時,最優算法從最後一個窗口總數中減去窗口左側的項目,並添加一個從右邊進來。如果你的解決方案需要較小的「H」值,你應該看到你的時間點會超過cumsum的時間。 – Jaime 2014-08-28 04:45:47

相關問題