КПКейсПрактика
Все материалы
Продуктовая аналитикапрактикумсредний

Pandas groupby и merge: как собрать аналитический отчёт из таблиц

Практический разбор groupby, merge и pivot_table в pandas: как агрегировать заказы, присоединять справочники и не посчитать выручку дважды.

КПКейсПрактика28 июля 2026 г.12 мин
Два аналитика соединяют таблицы и собирают итоговый отчёт в pandas.

В рабочей папке редко лежит одна идеальная таблица. Заказы находятся отдельно, пользователи — в справочнике, а маркетинговый канал приходит ещё одним файлом. В pandas аналитический отчёт обычно собирается в три шага: понять зерно каждой таблицы, агрегировать факты и только потом соединить их по ключу.

Коротко

`groupby` отвечает на вопрос “как посчитать показатель по группам”. `merge` соединяет таблицы по ключу. `pivot_table` превращает длинный результат в компактную матрицу. Все три операции простые по синтаксису, но ошибки в зерне легко превращают 10 заказов в 100 или незаметно теряют пользователей.

  • Перед операцией запиши, что означает одна строка в каждой таблице.
  • Сначала агрегируй факты до нужного уровня, потом присоединяй справочники.
  • Для контроля соединения проверяй количество строк и долю пропусков после merge.
  • Не используй `sum` для показателя, который уже был агрегирован выше.

Начни с зерна таблиц

Представим учебный набор: в `orders` одна строка — один заказ, в `order_items` одна строка — одна товарная позиция, в `users` одна строка — один пользователь. Если присоединить `users` к `order_items`, строки не должны умножиться: для каждого user_id в справочнике должна быть максимум одна запись.

Зерно и ключи в мини-схеме интернет-магазина
ТаблицаОдна строкаКлюч для соединения
ordersодин заказorder_id, user_id
order_itemsодна позиция внутри заказаorder_id, product_id
usersодин пользовательuser_id
productsодин товарproduct_id

groupby: агрегируй факты по смысловой группе

В `groupby` сначала укажи измерение, затем выбери поля и агрегаты. Для продуктового отчёта часто нужны не только сумма выручки, но и количество заказов, уникальные покупатели и средний чек. Явные имена агрегатов читаются лучше, чем цепочка из нескольких промежуточных таблиц.

Условная выручка по каналам после groupby

Пример показывает форму результата, а не реальные данные. Для решения добавь период и размер сегмента.

Выручка, тыс. ₽
pythonВыручка и покупатели по каналу
channel_report = (
    orders.groupby('channel', as_index=False)
    .agg(
        orders=('order_id', 'nunique'),
        buyers=('user_id', 'nunique'),
        revenue=('revenue', 'sum'),
        average_order=('revenue', 'mean'),
    )
    .sort_values('revenue', ascending=False)
)

channel_report['revenue_share'] = (
    channel_report['revenue'] / channel_report['revenue'].sum()
)

merge: соединяй таблицы после агрегации

Если тебе нужен канал в отчёте по заказам, сначала собери одну строку на заказ, а затем добавь атрибуты пользователя. `how="left"` сохраняет все строки левой таблицы и позволяет заметить пользователей, для которых справочник не нашёлся. `validate="many_to_one"` полезен как предохранитель: он упадёт, если справа ключ оказался неуникальным.

pythonПрисоединить справочник пользователей и проверить ключ
order_report = (
    orders[['order_id', 'user_id', 'channel', 'revenue']]
    .merge(
        users[['user_id', 'plan', 'country']],
        on='user_id',
        how='left',
        validate='many_to_one',
        indicator=True,
    )
)

missing_users = (
    order_report['_merge'].eq('left_only').mean()
)
Проверяй merge сразу после операции

Сравни количество строк до и после, долю _merge == left_only и уникальность ключа справа. Если число строк выросло неожиданно, это почти всегда сигнал о дубликатах в ключе или неверном зерне.

pivot_table: сделать отчёт читаемым

После группировки данные часто удобны для кода, но неудобны для просмотра. `pivot_table` раскладывает измерение по строкам и колонкам: например, выручку по каналам и планам. Это хороший последний шаг перед графиком или выгрузкой, но не замена проверке исходного зерна.

pythonМатрица выручки по каналу и тарифу
revenue_matrix = pd.pivot_table(
    order_report,
    index='channel',
    columns='plan',
    values='revenue',
    aggfunc='sum',
    fill_value=0,
)

revenue_matrix = revenue_matrix.sort_values('pro', ascending=False)

Как не посчитать выручку дважды

Самая дорогая ошибка возникает, когда заказ присоединяют к таблице позиций, а затем суммируют сумму заказа. Один заказ с четырьмя позициями появится четыре раза, и revenue вырастет в четыре раза. Если нужна аналитика товаров, агрегируй `order_items` по order_id или используй сумму позиций, но не смешивай её с готовой суммой заказа.

  • Сохрани контрольные числа: заказы, покупатели, выручка до соединения.
  • После merge сравни `nunique(order_id)` с исходным значением.
  • Для one-to-many заранее реши, нужен ли разворот на уровень позиции.
  • Не заполняй пропуски нулём, пока не понял, означает ли пропуск отсутствие факта.
Продолжить чтение
Вся библиотека