ускорить панд серии .rolling.appy () - PullRequest
1 голос
/ 26 октября 2019

Мне нужно вычислить произведение всех значений в скользящих окнах для серий панд, игнорировать nan.

Я использую pandas.Series.rolling.apply в качестве текущего подхода, но скорость довольно медленная по сравнению со встроенной-в функциях, я работаю на огромных фреймах данных, поэтому моей заботой является скорость.

в качестве демонстрации:

import pandas as pd
a = pd.Series(range(100))
%timeit -n100 a.rolling(5).apply(np.nanprod,raw=True)
5.58 ms ± 163 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

%timeit -n100 a.rolling(5).mean()
236 µs ± 19 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

Так что apply() намного медленнее по сравнению с-в mean функция

1 есть ли способ ускорить процесс применения

2 или есть встроенная функция продукта для скользящего окна (игнорируйте nan, если это возможно)? Не могу найти его в документах

Ответы [ 2 ]

1 голос
/ 26 октября 2019

Рецепт вашей проблемы: as_strided Функция Numpy.

Чтобы использовать ее, определите следующую функцию:

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

Затем вызовите np. nanprod по результату этой функции:

np.nanprod(roll_win(a.values, 5), axis=1)

Разница в том, что в результате получается массив Numpy 1-D, без 4 начальных NaN значения, но скорость должна быть значительно лучше.

0 голосов
/ 26 октября 2019

На самом деле существует функция .prod(), которая по умолчанию игнорирует значения NA / null.

...