Creating a tumbling windows in python

后端 未结 3 1113
离开以前
离开以前 2021-01-27 20:45

Just wondering if there is a way to construct a tumbling window in python. So for example if I have list/ndarray , listA = [3,2,5,9,4,6,3,8,7,9]. Then how could I f

相关标签:
3条回答
  • 2021-01-27 21:02

    If you want a one-liner, you can use list comprehension:

    listA = [3,2,5,9,4,6,3,8,7,9]
    listB=[max(listA[i:i+3]) for i in range(0,len(listA),3)]
    print (listB)
    

    it returns:

    [5, 9, 8, 9]
    

    Of course the codes can be written more dynamically: if you want a different window size, just change 3 to any integer.

    0 讨论(0)
  • 2021-01-27 21:12

    Using numpy, you can extend the list with zeroes so its length is divisible by the window size, and reshape and compute the maxalong the second axis:

    def moving_maxima(a, w):
        mod = len(a)%w
        d = w if mod else mod
        x = np.r_[a, [0]*(d-mod)]
        return x.reshape(-1,w).max(1)
    

    Some examples:

    moving_maxima(listA,2)
    # array([3., 9., 6., 8., 9.])
    
    moving_maxima(listA,3)
    #array([5, 9, 8, 9])
    
    moving_maxima(listA,4)
    #array([9, 8, 9])
    
    0 讨论(0)
  • 2021-01-27 21:14

    Approach #1: One-liner for windowed-max using np.maximum.reduceat -

    In [118]: np.maximum.reduceat(listA,np.arange(0,len(listA),3))
    Out[118]: array([5, 9, 8, 9])
    

    Becomes more compact with np.r_ -

    np.maximum.reduceat(listA,np.r_[:len(listA):3])
    

    Approach #2: Generic ufunc way

    Here's a function for generic ufuncs and that window length as a parameter -

    def windowed_ufunc(a, ufunc, W):
        a = np.asarray(a)
        n = len(a)
        L = W*(n//W)
        out = ufunc(a[:L].reshape(-1,W),axis=1)
        if n>L:
            out = np.hstack((out, ufunc(a[L:])))
        return out
    

    Sample run -

    In [81]: a = [3,2,5,9,4,6,3,8,7,9]
    
    In [82]: windowed_ufunc(a, ufunc=np.max, W=3)
    Out[82]: array([5, 9, 8, 9])
    

    On other ufuncs -

    In [83]: windowed_ufunc(a, ufunc=np.min, W=3)
    Out[83]: array([2, 4, 3, 9])
    
    In [84]: windowed_ufunc(a, ufunc=np.sum, W=3)
    Out[84]: array([10, 19, 18,  9])
    
    In [85]: windowed_ufunc(a, ufunc=np.mean, W=3)
    Out[85]: array([3.33333333, 6.33333333, 6.        , 9.        ])
    

    Benchmarking

    Timings on NumPy solutions on array data with sample data scaled up by 10000x -

    In [159]: a = [3,2,5,9,4,6,3,8,7,9]
    
    In [160]: a = np.tile(a, 10000)
    
    # @yatu's soln
    In [162]: %timeit moving_maxima(a, w=3)
    435 µs ± 8.54 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
    
    # From this post - app#1
    In [167]: %timeit np.maximum.reduceat(a,np.arange(0,len(a),3))
    353 µs ± 2.55 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
    
    # From this post - app#2
    In [165]: %timeit windowed_ufunc(a, ufunc=np.max, W=3)
    379 µs ± 6.44 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
    
    0 讨论(0)
自定义标题
段落格式
字体
字号
代码语言
提交回复
热议问题