PandasMiddleCoding
Чем transform() отличается от agg() при использовании с groupby()?
agg() схлопывает группу в одну строку (форма меняется), transform() возвращает Series той же длины что исходный DataFrame — это ключевое различие при выборе метода.
Ключевое различие: форма выходных данных
agg() уменьшает каждую группу до одной строки — результат содержит столько строк, сколько уникальных ключей. transform() возвращает объект той же длины и с тем же индексом, что исходный DataFrame: каждая строка получает значение, вычисленное для её группы. Это принципиально для feature engineering, когда нужно добавить групповую статистику как новый столбец без join.
agg — схлопывание групп
import pandas as pd
df = pd.DataFrame({
"dept": ["eng", "eng", "hr", "hr", "eng"],
"salary": [120_000, 95_000, 70_000, 80_000, 110_000],
})
# agg: 5 строк -> 2 строки (по числу групп)
agg_result = df.groupby("dept", as_index=False).agg(
mean_sal=("salary", "mean"),
count=("salary", "count"),
)
print(agg_result.shape) # (2, 3)
print(agg_result)
# dept mean_sal count
# 0 eng 108333.333333 3
# 1 hr 75000.000000 2
transform — broadcast обратно в исходный DataFrame
# transform: 5 строк -> 5 строк, каждой строке присваивается mean её группы
df["dept_mean_sal"] = df.groupby("dept")["salary"].transform("mean")
df["salary_pct_of_dept"] = df["salary"] / df["dept_mean_sal"]
print(df)
# dept salary dept_mean_sal salary_pct_of_dept
# 0 eng 120000 108333.33 1.108
# 1 eng 95000 108333.33 0.877
# 2 hr 70000 75000.00 0.933
# 3 hr 80000 75000.00 1.067
# 4 eng 110000 108333.33 1.015
Когда использовать что
- agg — нужна сводная таблица, отчёт, агрегат для дашборда.
- transform — добавляем признак в исходный DataFrame (group mean, rank, z-score), нормализация внутри группы, заполнение NaN групповым значением.
- apply — когда логика слишком сложна для agg/transform (возвращает произвольный объект), но медленнее.
Заполнение NaN через transform
df["salary"] = df["salary"].astype(float)
df.loc[2, "salary"] = float("nan") # симулируем пропуск
# Заполнить NaN медианой группы без merge
df["salary"] = df["salary"].fillna(
df.groupby("dept")["salary"].transform("median")
)
Ранжирование внутри группы
# transform("rank") возвращает float-ранг внутри группы
df["rank_in_dept"] = df.groupby("dept")["salary"].transform(
lambda x: x.rank(method="dense", ascending=False)
)
Подводные камни
- transform ожидает возврат той же длины — если функция возвращает скаляр, он транслируется; если Series другой длины — ValueError. agg такого ограничения не имеет.
- agg с as_index=True создаёт MultiIndex при нескольких ключах groupby; забытый reset_index() ломает последующий merge по плоским столбцам.
- Data leakage с transform — если вычислять групповое среднее на всём датасете (train+test) и добавлять как признак, модель получает информацию о test-выборке. Правило: fit transform только на train, затем apply через merge на test.
- transform медленнее agg для стандартных функций потому что результат надо broadcasting обратно; для строк > 10M разница становится заметной.
- Категориальные ключи без observed=True — groupby создаёт группы для всех категорий, transform вернёт NaN для строк несуществующих категорий, что неочевидно.
- transform('nunique') недоступен напрямую — нужно
transform(lambda x: x.nunique()), что значительно медленнее. - agg с несколькими функциями возвращает MultiIndex columns (
('salary', 'mean')); сглаживайте черезdf.columns = ['_'.join(c) for c in df.columns]. - sort в groupby влияет на transform('cumsum') — если sort=False, нарастающие агрегаты считаются в порядке появления строк в исходном DataFrame, а не по возрастанию ключа.
Common mistakes
- Объяснять
groupby transform vs aggтолько синтаксисом без shape, dtype, состояния или режима выполнения. - Игнорировать leakage, воспроизводимость, пустые входы и скрытые копии данных.
- Не проверять production-симптомы: latency, память, ретраи, дрейф качества и несовпадение версий.
What the interviewer is testing
- Может ли связать
groupby transform vs aggс реальным контрактом входов и выходов. - Упоминает ли тесты, метрики, reproducibility и диагностику ошибок.
- Видит ли различие между demo-кодом в ноутбуке и production-пайплайном.