🧐 Логика
Pandas, как и SQL, реализует парадигму Разделение‑Применение‑Объединение / Split‑Apply‑Combine:
- разбиваем данные на группы
- применяем к каждой группе функцию (медиану и т.д.)
- собираем результаты в новый
DataFrameЭто логика мышления, а не жёсткий порядок операций.
🆚️ Агрегации в SQL и Pandas
SQL:
- Быстрая агрегация внутри базы без перелива данных
- GROUP BY + COUNT, SUM, AVG, MIN, MAX, STRING_AGG, ARRAY_AGG
- Оконные функции (ROW_NUMBER, LAG, SUM OVER) — агрегация с сохранением строк
Pandas:
- Гибкая агрегация с произвольными функциями: .agg(['mean', 'std', custom_func])
- Трансформация с сохранением размера: .transform()
- Фильтрация групп: .filter(lambda x: len(x) > 5)
- Мультииндексные утилиты: unstack(), pivot_table()
👥 Агрегации по ролям
Аналитик
SQL — метрики по группам
Pandas — аномалии
Дата-сайентист (Data Scientist)
SQL — примеры (sample)
Pandas — генерация признаков (feature engineering)
Инженер данных (Data Engineer)
SQL — витрины
Pandas — прототипы
BI‑аналитик
SQL — вся агрегация в DWH
Pandas — ❌ не нужно
Продуктовый аналитик
SQL — 80% когорт
Pandas — 20% кастом
ML-инженер (Machine Learning Engineer)
SQL — выгрузка признаков (features, фичей)
Pandas — пайплайны
📊 Пример
import pandas as pd
df = pd.DataFrame({
'ch': ['ya', 'vk', 'ok', None, 'tg'],
'cost': [5000, 5000, 500, 500, None],
'revenue': [30000, 10000, None, 40000, 30000]
})🌟 Синтаксис groupby
df.groupby('ch')['cost'].sum()df — объект DataFrame.groupby() — метод группировки['cost'] — выбор данных.sum() — метод агрегации🐍 Типы скобок в Python
( ) — вызов функции/метода
[ ] — доступ к элементу
👥 Группировка
groupby() только группирует данные, не считает их.Результат появляется при добавлении агрегации:
sum(), mean() и т.д.df.groupby('ch')[['cost', 'revenue']].sum()Результат —
DataFrame: потеряли 40k выручки 🤯 cost revenue
ch
ok 500.0 0.0
tg 0.0 30000.0
vk 5000.0 10000.0
ya 5000.0 30000.0Почему?
`0.0`, а не `0`: если есть
None → Pandas автоматически приводит всю колонку к типу float64нет строки с
NaN: по умолчанию строки с None в ключе группировки исключаются из результата groupby(dropna=True)dropna=False — чтобы вернуть, см. ниже.0️⃣ NaN или 0?
Зависит от:
1) метода агрегации
2) объекта агрегации
1️⃣ Методы
sum и count возвращают число, все остальные — NaN:• .sum() → пустая сумма = 0• .mean() → нечего усреднять = NaN• .count() → ноль штук = 0• .min() → не из чего выбирать = NaN• .max() → NaN• .std() → NaN2️⃣
NaN в ключе группировки — другие правила-
NaN в значениях (revenue, cost) → правила агрегации (см. таб. выше)-
NaN в ключе группировки (ch) → зависит от dropna:`dropna=True` (по умолчанию): → строки с None в ключе исключаются`dropna=False`: → None становится отдельной группой, внутри — те же правила агрегацииdf.groupby('ch', dropna=False)[['cost', 'revenue']].sum()Результат:
cost revenue
ch
NaN 500.0 40000.0
ok 500.0 0.0
tg 0.0 30000.0
vk 5000.0 10000.0
ya 5000.0 30000.0# появилась группа NaN и 40k 🥳💡 Альтернатива:
fillna(0)Чтобы цифры сходились, меняем
None на 0 (везде):df.fillna(0).groupby('ch')['revenue'].mean()🤔
Series или DataFrame?Pandas определяет автоматически по результату:
df['cost'] → Series (одинарные скобки)
df[['cost']] → DataFrame (двойные скобки).groupby() аналогично:- одна колонка (агрегация) →
Series- две+ колонок (агрегации) →
DataFrame➕ Несколько агрегаций через agg
df.groupby('ch')['revenue'].agg(['sum', 'mean'])
💡 transform — среднее внутри каждой группыdf['mean_ch'] = df.groupby('ch')['revenue'].transform('mean')Результат:
ch cost revenue mean_ch
0 ya 5000.0 30000.0 30000.0
1 vk 5000.0 10000.0 10000.0
2 ok 500.0 NaN NaN
3 None 500.0 40000.0 NaN
4 tg NaN 30000.0 30000.0🎯 transform полезен для:
- нормализации
- расчёта долей
- заполнения пропусков
💬 Далее:
Сводные таблицы — pivot_table