Numpy中1D阵列的滚动窗口?

时间:2011-07-25 02:04:52

标签: python numpy window

有没有办法在Numpy中有效实现1D数组的滚动窗口?

例如,我有这个纯Python代码片段来计算一维列表的滚动标准偏差,其中observations是一维值列表,n是标准的窗口长度偏差:

stdev = []
for i, data in enumerate(observations[n-1:]):
    strip = observations[i:i+n]
    mean = sum(strip) / n
    stdev.append(sqrt(250*sum([(s-mean)**2 for s in strip])/(n-1)))

有没有办法在Numpy中完全执行此操作,即没有任何Python循环?标准偏差对于numpy.std来说是微不足道的,但滚动窗口部分完全让我感到困惑。

我在Numpy找到了关于滚动窗口的this博文,但它似乎不适用于1D阵列。

6 个答案:

答案 0 :(得分:50)

只需使用博客代码,但将您的功能应用于结果。

numpy.std(rolling_window(observations, n), 1)

你在哪里(来自博客):

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

答案 1 :(得分:6)

我尝试在形状为[samples, features]的2D数组上使用so12311answer listed above,以便获得形状为[samples, timesteps, features]的输出数组以用于卷积或lstm神经网络,但效果不佳。在研究了跨步的工作原理后,我意识到它是沿着最后一个轴移动窗口,因此我做了一些调整,使窗口沿着第一个轴移动:

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

注意:如果仅使用一维输入数组,则输出没有差异。在我的搜索中,这是第一个接近我想要做的结果的结果,因此,我添加了此结果,以帮助其他人搜索相似的答案。这也是我的第一个答案,所以请让我知道有关更好地格式化和提交答案的建议。

答案 2 :(得分:4)

Numpy 1.20开始,可以直接用sliding_window_view获取滚动窗口:

from numpy.lib.stride_tricks import sliding_window_view

sliding_window_view(np.array([1, 2, 3, 4, 5, 6]), window_shape = 3)
# array([[1, 2, 3],
#        [2, 3, 4],
#        [3, 4, 5],
#        [4, 5, 6]])

答案 3 :(得分:0)

def moving_avg(x,n):
    mv =  np.convolve(x,np.ones(n)/n,mode='valid')
    return np.concatenate(([np.NaN for k in range(n-1)],mv))

答案 4 :(得分:0)

只有一行代码...

pd.Series(observations).rolling(n).std()

答案 5 :(得分:0)

基于后面的答案,我在这里添加了滚动一维 numpy 数组的代码,选择窗口大小窗口步频

a = np.arange(50)

def rolling_window(array, window_size,freq):
    shape = (array.shape[0] - window_size + 1, window_size)
    strides = (array.strides[0],) + array.strides
    rolled = np.lib.stride_tricks.as_strided(array, shape=shape, strides=strides)
    return rolled[np.arange(0,shape[0],freq)]

rolling_window(a,10,5)

输出:

array([[ 0,  1,  2,  3,  4,  5,  6,  7,  8,  9],
       [ 5,  6,  7,  8,  9, 10, 11, 12, 13, 14],
       [10, 11, 12, 13, 14, 15, 16, 17, 18, 19],
       [15, 16, 17, 18, 19, 20, 21, 22, 23, 24],
       [20, 21, 22, 23, 24, 25, 26, 27, 28, 29],
       [25, 26, 27, 28, 29, 30, 31, 32, 33, 34],
       [30, 31, 32, 33, 34, 35, 36, 37, 38, 39],
       [35, 36, 37, 38, 39, 40, 41, 42, 43, 44],
       [40, 41, 42, 43, 44, 45, 46, 47, 48, 49]])