Применять на скользящем фрейме слишком медленно (pandas 0.23.4) - PullRequest
0 голосов
/ 17 декабря 2018

У меня есть фрейм данных, где для нескольких продуктов за несколько дат у меня есть несколько числовых величин, по которым я хочу рассчитать скользящие метрики:

df = pd.DataFrame(data=data, columns=['DATE', 'PRODUCTS', 'NUMQUANTITY_1', 'NUMQUANTITY_2', ..., 'NUMQUANTITY_20'])

Я делаю следующие вычисления:

rolling_calculations = df.groupby('CATEGORY')\
.rolling('7D', on='DATE',closed='left')\
.apply(np.nanmean, raw=True)

, которые работают, но работают довольно медленно: для примерно 2 миллионов строк и 20 NUMQUANTITY на моем ноутбуке требуется около 30 минут для вычисления скользящего np.nanmean.

Есть ли способы ускорить процесс?

Спасибо за помощь

1 Ответ

0 голосов
/ 17 декабря 2018

Я думаю, что использование функции mean, встроенной в панд, даст вам значительное увеличение скорости, хотя полная операция может все же занять некоторое время.

Начните с:

N = 1000
x = numpy.random.uniform(size=(N, 5))
dates = pandas.date_range(start='1910-01-01', freq='5T', periods=N, name='DATE')

nums = pandas.DataFrame(data=x, columns=list('ABCDE'), index=dates)
cats = pandas.DataFrame({'CATEGORY': numpy.random.choice(list('abcdefghi'), size=N)}, index=dates)

df = nums.join(cats).reset_index()
df.loc[df['A'] < 0.5, list('ABCDE')] = numpy.nan
roll = df.groupby('CATEGORY').rolling('7D', on='DATE',closed='left')

Производительность намного лучше с:

%%timeit
roll.mean()

# 88.1 ms ± 2.34 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)

Than:

%%timeit
roll.apply(numpy.nanmean, raw=True)

# 658 ms ± 96.8 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

И просто для проверки работы следующее не поднимает AssertionError:

x = roll.mean()
y = roll.apply(numpy.nanmean, raw=True)
pandas.util.testing.assert_frame_equal(x, y)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...