Pandas Resampling Code работает крайне медленно - PullRequest
1 голос
/ 17 апреля 2019

Мне нужно повторить выборку некоторых данных в Pandas, и я использую код ниже:

На мои данные уходит 5 hours.

df['date'] = pd.to_datetime(df['date'], format='%y-%m-%d')
df = df.set_index('date')
df.groupby('id').resample('D')['value'].agg('sum').loc[lambda x: x>0]

Это слишком медленно.

Как ускорить приведенный выше код для таких данных:

id    date    value

1   16-12-1     9
1   16-12-1     8
1   17-1-1      18
2   17-3-4      19
2   17-3-4      20
1   17-4-3      21
2   17-7-13     12
3   17-8-9      12
2   17-9-12     11
1   17-11-12    19
3   17-11-12    21

giving output:

id  date      
1   2016-12-04    17
    2017-01-01    18
    2017-04-09    21
    2017-11-12    19
2   2017-03-05    39
    2017-07-16    12
    2017-09-17    11
3   2017-08-13    12
    2017-11-12    21
Name: value, dtype: int64

Я настроил дату в качестве индекса, но код работает очень медленно.Любая помощь будет великолепна.

1 Ответ

2 голосов
/ 17 апреля 2019

Дайте это попробовать.Я собираюсь использовать pd.Grouper() и указывать частоту ежедневной, надеясь, что она будет быстрее.Кроме того, я избавляюсь от agg и сразу использую .sum().

df['date'] = pd.to_datetime(df['date'], format='%y-%m-%d')
df = df.set_index('date')
df2 = df.groupby(['id',pd.Grouper(freq='D')])['value'].sum()

Результаты:

id  date      
1   2016-12-01    17
    2017-01-01    18
    2017-04-03    21
    2017-11-12    19
2   2017-03-04    39
    2017-07-13    12
    2017-09-12    11
3   2017-08-09    12
    2017-11-12    21

Надеюсь, это сработает.

[РЕДАКТИРОВАТЬ]

Итак, я только что провел небольшой тест между обоими методами для случайно сгенерированного df с 100000 строками

df = pd.DataFrame(np.random.randint(0, 30,size=100000),
                  columns=["id"],
                  index=pd.date_range("19300101", periods=100000))
df['value'] = np.random.randint(0, 10,size=100000)

и попробовал его на обоих кодах, и результаты:

для использования resmple:

startTime = time.time()
df2 = df.groupby('id').resample('D')['value'].agg('sum').loc[lambda x: x>0]
print(time.time()-startTime)
1.0451831817626953 seconds

для использования pd.Grouper():

startTime = time.time()
df3 = df.groupby(['id',pd.Grouper(freq='D')])['value'].sum()
print(time.time()-startTime)
0.08430838584899902 seconds

, поэтому примерно 12 раз быстрее! (если моя математика верна)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...