8wDlpd.png
8wDFp9.png
8wDEOx.png
8wDMfH.png
8wDKte.png

Numpy 中一维数组的滚动窗口?

Trickfinger 2月前

65 0

有没有办法在 Numpy 中有效地实现一维数组的滚动窗口?例如,我有一段纯 Python 代码片段来计算一维列表的滚动标准差,其中

有没有办法在 Numpy 中有效地实现一维数组的滚动窗口?

例如,我有这段纯 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 中的滚动窗口的博客文章,但它似乎不适用于一维数组。

帖子版权声明 1、本帖标题:Numpy 中一维数组的滚动窗口?
    本站网址:http://xjnalaquan.com/
2、本网站的资源部分来源于网络,如有侵权,请联系站长进行删除处理。
3、会员发帖仅代表会员个人观点,并不代表本站赞同其观点和对其真实性负责。
4、本站一律禁止以任何方式发布或转载任何违法的相关信息,访客发现请向站长举报
5、站长邮箱:yeweds@126.com 除非注明,本帖由Trickfinger在本站《numpy》版块原创发布, 转载请注明出处!
最新回复 (0)
  • 只需使用博客代码,但将您的功能应用于结果。

    IE

    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)
    
  • @Gulzar,如果您还没有,请查看下面的答案。so12311 的函数实际上适用于沿最后一个轴移动窗口的 nd 数组。我的函数适用于沿第一个轴移动窗口的 nd 数组。如果您需要沿中间轴滚动,则需要拆分步幅和形状,并在适当的位置添加额外的元素。我不知道您所说的重叠是什么意思,但您可能可以通过不同的步幅和形状来实现它。考虑提出一个新问题,详细说明您具体需要什么。

  • @LelandHepworth 谢谢。我所说的重叠是指数组 [1, 2, 3, 4, 5] 的例子,我想要某种方法来获得 [1, 2, 3], [2, 3, 4], [3, 4, 5] 的例子。

  • @Gulzar,使用任一版本的函数,以下内容都应该可以得到你想要的:rolling_window(np.array([1, 2, 3, 4, 5]), 3)

  • 从开始 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]])
    
  • 为了增加步幅,可以使用切片:sliding_window_view(np.array([1, 2, 3, 4, 5, 6]), window_shape = 3)[::stride] 我知道 stride_tricks 实现了这一点,但是警告信息让我犹豫是否使用它,而这个技巧可以很好地处理它。

  • 我尝试 so12311 上面列出的 so12311 [samples, features] ,以便获得具有形状的输出数组, [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)
    

    注意:如果您仅使用 1D 输入数组,则输出没有差异。在我的搜索中,这是第一个接近我想要的结果,所以我添加它来帮助其他搜索类似答案的人。

  • 仅需一行代码...

    import pandas as pd
    
    pd.Series(observations).rolling(n).std()
    
  • 根据后面的答案,我在这里添加了用于滚动 1-D 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]])
    
    
  • 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))
    
  • 引用 12

    我需要一个滚动窗口来应用于 n 维数组的任何中间轴,因此我扩展了已接受的答案和 @Miguel Gonzalez 的代码。将滚动窗口沿任意轴应用于 nd 数组的相应代码:

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

    创建测试来断言函数有效性的示例:

        arr = np.random.randint(1, 1000, size=(2,108,21,5))
        arr_windowed = rolling_window_ndimensional(arr, 12, 12, axis=1)
    
        print(arr.shape)
        print(arr_windowed.shape)
        np.allclose(arr, arr_windowed.reshape(2,-1, 21,5))
    
返回
作者最近主题: