Соединение по времени в pandas
Вопрос
Есть события пользователей и таблица смены тарифов (user_id, changed_at, plan). Нужно для каждого события знать тариф пользователя на момент события. Как сделаете в pandas?
Попробуйте сами
Ответьте вслух за 2 минуты, как на собесе. Потом сверьтесь с тезисами: что прозвучало, а что нет.
Показать ответ и разбор
Коротко
Что должно прозвучать в ответе
Обычный merge по user_id размножит строки на каждую смену тарифа
`pd.merge_asof(events, plans, left_on="ts", right_on="changed_at", by="user_id")`
Обе таблицы отсортированы по времени
`direction="backward"`: последнее значение не позже события
События до первой смены тарифа получат NaN: заполнить тарифом по умолчанию
Проверить часовые пояса и тип datetime у обеих колонок
Что могут спросить следом
- Как сделать то же самое в SQL?
- Что если смены тарифа приходят с опозданием?
- Как ограничить давность найденного значения?
Разбор
Обычный merge по user_id склеит каждое событие со всеми сменами тарифа, а потом придётся выбирать нужную, это дорого. В pandas для этого есть merge_asof: pd.merge_asof(events.sort_values("ts"), plans.sort_values("changed_at"), left_on="ts", right_on="changed_at", by="user_id", direction="backward"). Для каждого события он берёт последнюю смену тарифа этого пользователя не позже события. Обе таблицы должны быть отсортированы по времени, а колонки времени одного типа и в одном часовом поясе. События до первой смены получат NaN, их заполняю стартовым тарифом. Если нужно отсечь слишком старые значения, есть параметр tolerance. В SQL то же делают через LATERAL с ORDER BY changed_at DESC LIMIT 1.
Ответьте сами, а не прочитайте
В тренажёре вопрос попадёт в повторения и вернётся, когда начнёт забываться. Плюс билеты с зачётом: 20 вопросов, не больше 2 ошибок.