2013年12月12日

fast rolling window

假設有兩個array S1 (size m), S2 (size n), m>n,要計算S2相對於S1的滑動函數值(如mean或是std等),一般的做法是使用loop實作,但是python的迴圈速度相當的慢,所以建議使用numpy strides的功能來加速,在測試當中,計算stdev大約能夠加速100倍,程式碼如下:

def rolling_window(a, window):
    shape = a.shape[:-1] + (a.shape[-1] - window + 1, window)
    print shape
    strides = a.strides + (a.strides[-1],)
    return np.lib.stride_tricks.as_strided(a, shape=shape, strides=strides)

def test_rolling_window(winsize=3):
    import time
    t = time.clock()
    observations = np.random.randn(1000)
    np.std(rolling_window(observations, winsize), 1)
    print "strided %.6f secs"%(time.clock()-t)

    t = time.clock()
    for idx in xrange(winsize, len(observations)):
        np.std(observations[idx-winsize: idx])
    print "loop %.6f secs"%(time.clock()-t)