Лямбда-функция панд ... Более быстрое вычисление - PullRequest
0 голосов
/ 01 октября 2019

У меня есть следующие dataframe из dates и codes.

df = pd.DataFrame(
    {'date': list(pd.date_range(start='2018-01-01', end='2018-12-30')) * 364,
     'code': np.random.permutation(list(np.arange(23001, 23001 + 8281)) * 16)}
).sort_values('date', ascending=True).reset_index(drop=True)

Я хотел бы, чтобы для каждого code, произошедшего в specific time, считалось все идентичное code, которое произошло до или в ту же дату.

def nb_code_at_date(x):
    condition = (df['date'] <= x['date'])
    return (df.loc[condition, 'code'] == x['code']).sum()

Очевидно, что проблема заключается в времени, необходимом для вычисления этого для «большого» фрейма данных:

%%timeit
df.head(1000).apply(lambda x: nb_code_at_date(x), axis=1)
>> 2.89 s ± 283 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

Как бы вы поступили, чтобы увеличить это время ожидания?

Ответы [ 2 ]

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

Задача может быть выполнена с использованием GroupBy.cumcount и GroupBy.transform:

output = df.join(df.groupby(["code"]).cumcount().add(1).to_frame())
output = output.groupby(["code", "date"]).transform("max")
0 голосов
/ 01 октября 2019

Другое решение, которое я нашел, заключается в использовании функции pandas.crosstab для вычисления предварительно определенного кадра данных, готового к использованию и исправленного.

temp = pd.crosstab(df['date'], df['code'])

def nb_code_at_date2(x):
    condition = (temp.index <= x['date'])
    return (temp.loc[condition, x['code']]).sum()

%%timeit
df.head(1000).apply(lambda x: nb_code_at_date2(x), axis=1)
>>750 ms ± 73.3 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...