【问题标题】:Rolling maximum with numpy使用 numpy 滚动最大值
【发布时间】:2018-09-07 08:35:49
【问题描述】:

这会在长度为 K 的滑动窗口上计算 A 的“滚动最大值”(类似于滚动平均值):

import numpy as np
A = np.random.rand(100000)
K = 10
rollingmax = np.array([max(A[j:j+K]) for j in range(len(A)-K)])

但我认为它在性能方面远非最佳。

我知道pandas 库有rolling_max,但是在我的项目中,我不想使用这个新的依赖。

问题:有没有一种简单的方法可以仅使用 numpy 计算滚动最大值?

【问题讨论】:

标签: python numpy


【解决方案1】:

我猜这个使用stridesas_strided 的小技巧可以完成这项工作:

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

出于比较目的,我根据您的算法定义了另一个函数:

def max_rolling2(A,K):
    rollingmax = np.array([max(A[j:j+K]) for j in range(len(A)-K)])
    return rollingmax

timeit 在我的笔记本电脑上的比较是:

与:

A = np.random.rand(100000)
K = 10


%timeit X = max_rolling2(A,K)
170 ms ± 19.8 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
%timeit X = max_rolling1(A,K)
> 3.75 ms ± 479 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

【讨论】:

    【解决方案2】:

    解决方案与此处的Divakar's answer 完全相似(完全归功于他),但在此上下文中,数组的最终裁剪具有不同的索引:

    maximum_filter1d(A, size=K)[K//2:-((K+1)//2)]
    

    例子:

    import numpy as np
    from scipy.ndimage.filters import maximum_filter1d
    A = np.random.randint(0, 10, (50))
    K = 5
    rollingmax = np.array([max(A[j-K:j]) for j in range(K,len(A))])
    rollingmax2 = np.array([max(A[j:j+K]) for j in range(len(A)-K)])
    rollingmax3 = maximum_filter1d(A,size=K)[K//2:-((K+1)//2)]
    print A, rollingmax, rollingmax2, rollingmax3
    

    [6 7 7 9 4 5 4 7 2 0 3 3 5 9 4 6 6 1 5 2 7 5 7 7 5 6 0 9 0 5 9 3 7 1 9 5 3 7 5 1 6 9 6 0 5 1 5 5 4 9]
    [9 9 9 9 7 7 7 7 5 9 9 9 9 9 6 6 7 7 7 7 7 7 7 9 9 9 9 9 9 9 9 9 9 9 9 7 7 9 9 9 9 9 6 5 5]
    [9 9 9 9 7 7 7 7 5 9 9 9 9 9 6 6 7 7 7 7 7 7 7 9 9 9 9 9 9 9 9 9 9 9 9 7 7 9 9 9 9 9 6 5 5]
    [9 9 9 9 7 7 7 7 5 9 9 9 9 9 6 6 7 7 7 7 7 7 7 9 9 9 9 9 9 9 9 9 9 9 9 7 7 9 9 9 9 9 6 5 5]

    【讨论】:

      【解决方案3】:

      很高兴找到这些解决方案 - 直到我尝试使用较大的 K 值。 有一个 ~6M 浮点数的数组,K = 25000....需要很长时间

      【讨论】:

      • 您找到更好的解决方案了吗?如果你找到一个,请发布一个完整的答案(这更像是一个评论)。
      猜你喜欢
      • 2019-10-06
      • 1970-01-01
      • 1970-01-01
      • 2014-05-09
      • 2017-08-27
      • 1970-01-01
      • 2017-10-13
      • 2023-03-15
      • 1970-01-01
      相关资源
      最近更新 更多