← К списку уроков
Python·Средний·12 мин

GroupBy и pivot_table в pandas

Агрегация данных в pandas: groupby, pivot_table, агрегатные функции.

GroupBy и pivot_table в pandas

groupby — это SQL GROUP BY в pandas. pivot_table — это сводная таблица Excel. Оба про одно: агрегации по группам.

Базовый groupby

df.groupby('city')['sales'].sum()

Возвращает Series: индекс = город, значение = сумма продаж.

Несколько агрегаций сразу

df.groupby('city').agg(
    total_sales=('sales', 'sum'),
    avg_check=('sales', 'mean'),
    n_orders=('order_id', 'nunique'),
)

Возвращает DataFrame с понятными именами колонок. Лучше чем словарь.

Многоуровневая группировка

df.groupby(['city', 'category'])['sales'].sum()

Возвращает Series с MultiIndex. Преобразуй в DataFrame:

df.groupby(['city', 'category'])['sales'].sum().reset_index()
# или
df.groupby(['city', 'category'], as_index=False)['sales'].sum()

pivot_table — сводная таблица

df.pivot_table(
    index='city',
    columns='category',
    values='sales',
    aggfunc='sum',
    fill_value=0
)

Получаем матрицу: строки = города, столбцы = категории, значения = сумма продаж. Эквивалент сводной в Excel.

groupby vs pivot_table

groupbypivot_table
Структурадлинная (long)широкая (wide)
Удобно длядальнейших операцийвизуализации
Несколько метрикчерез .agg()через несколько values
Скоростьбыстреечуть медленнее

Transform — групповые расчёты, форма сохраняется

df['city_avg'] = df.groupby('city')['sales'].transform('mean')
df['vs_city_avg'] = df['sales'] - df['city_avg']

transform отдаёт результат той же длины что исходный DataFrame — удобно для отклонений и нормализаций.

Filter — оставить только группы по условию

df.groupby('city').filter(lambda g: len(g) >= 10)

Оставит строки только из городов с 10+ заказами.

Что важно запомнить

  • as_index=False или .reset_index() чтобы получить плоский DataFrame
  • Имена колонок через agg(new_name=('col', 'func')) — стандарт с pandas 0.25+
  • transformagg: transform сохраняет размер DataFrame
  • На больших данных groupby('A').sum() гораздо быстрее чем for цикл — векторизация
  • Объединение нескольких: groupby('A').agg({'B': 'sum', 'C': 'mean'}) — старый стиль, тоже работает