pandas: группировки, соединения и упорядоченные показатели

groupby и agg: сводные показатели с явными именами агрегатов

Содержание курса

Named aggregation в agg: несколько агрегатов за один вызов

Когда у тебя есть сгруппированный объект, следующий вопрос — что именно вычислять по каждой группе. Самый гибкий способ — вызов .agg() с именованными парами.

Синтаксис выглядит так:

df.groupby('region', as_index=False).agg(
    total_sales=('sales', 'sum'),
    avg_units=('units', 'mean')
)

Каждая именованная пара — это отдельный аргумент вида имя_результата=(столбец, функция). Слева от = — имя, которое получит новый столбец в итоговой таблице. В кортеже справа — исходный столбец, из которого берутся данные, и строковое имя агрегирующей функции.

В этом курсе используются строки 'sum', 'mean', 'min', 'max', 'count' — это не исчерпывающий список агрегатов pandas, но достаточный для большинства задач. Их можно комбинировать в любом порядке и количестве в одном вызове.

Важный нюанс про 'count': он считает непропущенные значения в указанном столбце. Если в sales есть NaN, такая строка не попадёт в счётчик. Это поведение соответствует логике «сколько реальных продаж зафиксировано», а не «сколько строк в группе».

Вот полный пример с несколькими агрегатами одновременно:

import pandas as pd

df = pd.DataFrame({
    'region':   ['Север', 'Юг', 'Север', 'Юг', 'Север'],
    'category': ['A', 'A', 'B', 'B', 'A'],
    'sales':    [100, 200, 150, 300, 80],
    'units':    [10, 20, 15, 30, 8]
})

result = df.groupby('region', as_index=False).agg(
    total_sales=('sales', 'sum'),
    avg_units=('units', 'mean'),
    min_sales=('sales', 'min'),
    nonmissing_count=('sales', 'count')
)
print(result)

Вывод:

  region  total_sales  avg_units  min_sales  nonmissing_count
0  Север          330       11.0         80                 3
1    Юг           500       25.0        200                 2

Четыре именованные пары — четыре столбца в результате. Каждый столбец берёт данные из нужного исходного столбца независимо: total_sales и min_sales смотрят в sales, avg_units — в units, nonmissing_count считает непропущенные значения в sales.

Главное преимущество такого синтаксиса — имена столбцов результата ты задаёшь явно, прямо в вызове. Без named aggregation pandas генерировал бы технические имена вроде sales или строил MultiIndex в заголовках — ни то ни другое не читается в реальном коде. С именованными парами таблица сразу выходит с понятными заголовками, которые не нужно переименовывать потом через rename().

Один вызов .agg() с несколькими именованными парами заменяет несколько последовательных вычислений и возвращает всё в одной таблице. Именно этот паттерн используется в курсе как стандартный способ агрегирования.