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-пайплайном.

Sources

Related topics