Создание кувырка windows в python - PullRequest
0 голосов
/ 30 марта 2020

Просто интересно, есть ли способ построить падающее окно в python. Так, например, если у меня есть список / ndarray, listA = [3,2,5,9,4,6,3,8,7,9]. Тогда как я могу найти максимум первых 3 элементов (3,2,5) -> 5, а затем следующие 3 элемента (9,4,6) -> 9 и так далее ... Вроде как разбить его до разделов и нахождение макс. Таким образом, окончательный результат будет список [5,9,8,9]

Ответы [ 3 ]

1 голос
/ 30 марта 2020

Если вам нужен однострочный, вы можете использовать понимание списка:

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)

возвращает:

[5, 9, 8, 9]

Конечно, коды можно писать более динамично: если вы хотите другой размер окна, просто измените 3 на любое целое число.

1 голос
/ 30 марта 2020

Используя numpy, вы можете расширить список нулями, чтобы его длина делилась на размер окна, а также изменить и вычислить max вдоль второй оси:

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)

Некоторые примеры:

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])
1 голос
/ 30 марта 2020

Подход № 1: Однострочник для оконного макс. Использования np.maximum.reduceat -

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

Становится более компактным с np.r_ -

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

Подход № 2: Generi c ufun c way

Вот функция для generi c ufuncs и длина этого окна в качестве параметра -

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

Пробный прогон -

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])

На других уфунках -

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.        ])

Бенчмаркинг

Время на NumPy решениях для данных массива с увеличением выборочных данных на 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)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...