Панды - очень медленно при использовании groupby () с Rolling () и apply ()

У меня очень низкая производительность при вызове groupby вместе с накатыванием и применением функций для большого фрейма данных в Pandas (1500682 строк). Я пытаюсь получить скользящее среднее с разными весами.

Часть кода, которая работает медленно:

df['rolling'] = df.groupby('i2')['x'].rolling(3).apply(lambda x: x[-3]*0.1+x[-2]*0.9).reset_index(level=0, drop=True).reindex(df.index)

И полный код (с данными):

import pandas as pd
from random import randint


# data (it takes some time to create [less than 1 minute in my computer])
data1   = [[[[randint(0, 100) for i in range(randint(1, 2))] for i in range(randint(1, 3))] for i in range(5000)] for i in range(100)]
data2   = pd.DataFrame(
    [
        (i1, i2, i3, i4, x4)
        for (i1, x1) in enumerate(data1)
        for (i2, x2) in enumerate(x1)
        for (i3, x3) in enumerate(x2)
        for (i4, x4) in enumerate(x3)
    ],
    columns = ['i1', 'i2', 'i3', 'i4', 'x']
)
data2.drop(['i3', 'i4'], axis=1, inplace = True)
df   = data2.set_index(['i1', 'i2']).sort_index()


## conflicting part of the code ##
df['rolling'] = df.groupby('i2')['x'].rolling(3).apply(lambda x: x[-3]*0.1+x[-2]*0.9).reset_index(level=0, drop=True).reindex(df.index)

Если бы вы могли разработать код, чтобы сделать его более эффективным и быстрее выполнять, я был бы очень признателен.

Всего 1 ответ


Если я вас правильно понимаю, вы можете попробовать:

grp=df.groupby('i2')['x']
df['rolling']=grp.shift(2).mul(0.1).add(grp.shift(1).mul(0.9))

Теперь уточним:

Почему бы .apply(...) :

Когда мне следует использовать pandas apply () в моем коде?

Вместо этого вам следует использовать все, что использует векторизованные операции. Я поместил здесь более подробное объяснение:

https://stackoverflow.com/a/60029108/11610186


Есть идеи?

10000