Ускорить groupby.apply
Вопрос
Пайплайн считает метрики по пользователям через groupby("user").apply(custom_fn) и занимает 40 минут. Как будете ускорять?
Попробуйте сами
Ответьте вслух за 2 минуты, как на собесе. Потом сверьтесь с тезисами: что прозвучало, а что нет.
Показать ответ и разбор
Коротко
Что должно прозвучать в ответе
Профилирую: где время, сколько групп, что делает функция
Разбиваю функцию на встроенные агрегаты и `transform`
Условия через маски и `where` до группировки, а не внутри функции
Сортировка плюс `shift`, `cumsum`, `diff` в группе вместо цикла по строкам
Сократить данные: нужные колонки, типы `category`, фильтр до группировки
Если не хватает: Polars или DuckDB, вынос в SQL
Что могут спросить следом
- Как переписать «первый заказ после регистрации» без apply?
- Когда Polars реально даст выигрыш?
- Как проверить, что новая версия считает то же самое?
Разбор
Сначала измеряю: сколько групп, сколько строк, что делает функция. Почти всегда тормозит не pandas, а Python-вызов на каждую из миллионов групп. Дальше разбираю custom_fn на части: суммы, средние и счётчики переписываю на встроенные агрегаты через именованную агрегацию, условные метрики считаю так: сначала колонка-маска на всём DataFrame (df["paid"] = df["amount"].where(df["status"] == "ok", 0)), потом обычный sum по группам. Последовательную логику внутри группы заменяю сортировкой и групповыми shift, diff, cumsum. Уменьшаю данные: только нужные колонки, строки category, фильтр до группировки. Новую версию сверяю со старой на выборке через assert_frame_equal. Если и этого мало, переношу расчёт в DuckDB или Polars, они параллелят группировку по ядрам.
Ответьте сами, а не прочитайте
В тренажёре вопрос попадёт в повторения и вернётся, когда начнёт забываться. Плюс билеты с зачётом: 20 вопросов, не больше 2 ошибок.
Термины по теме
Ещё по теме «groupby и агрегаты»
- groupby: agg или transform
- Почему groupby.apply медленный
- as_index=False в groupby
- Отбор клиентов по условиям на группу
- Выручка и число клиентов по городам на pandas
- Доля заказа в выручке города: transform
- Топ-N заказов в каждом городе на pandas
- dropna=False в groupby