Skip to content

Pandas GroupBy: Aggregation, Transform, Apply (Guia 2025)

Updated on

O padrão split-apply-combine é o ponto forte do Pandas. A dificuldade: escolher entre agg, transform ou apply, além de lidar com ordenação, grupos ausentes ou SettingWithCopy.

Estrutura PAS:

  • Problema: Cálculos agrupados parecem opacos e lentos quando só precisamos de totais ou razões por linha.
  • Agitar: Usar apply em excesso ou esquecer as_index=False gera formas inesperadas, colunas duplicadas e pipelines lentos.
  • Solução: Poucos padrões bastam—agg para resumos, transform para métricas por linha, apply apenas quando necessário—com opções claras de ordenação e tratamento de grupos faltantes.

Guia rápido: quando usar cada método

MétodoForma retornadaMelhor paraExemplo
agg / aggregateUma linha por grupoResumos e múltiplas métricasdf.groupby("team").agg(avg_score=("score","mean"))
transformMesma quantidade de linhasFeatures por linha baseadas no grupodf["z"] = df.groupby("team")["score"].transform("zscore")
applyFlexívelCasos complexos fora de agg/transformdf.groupby("team").apply(custom_fn)

Dados de exemplo

import pandas as pd
 
data = {
    "team": ["A", "A", "B", "B", "B", "C"],
    "player": ["x1", "x2", "y1", "y2", "y3", "z1"],
    "score": [9, 7, 8, 6, 10, 3],
    "minutes": [30, 25, 28, 32, 20, 15],
}
df = pd.DataFrame(data)

Padrões de agregação (agg)

summary = (
    df.groupby("team", as_index=False)
      .agg(
          avg_score=("score", "mean"),
          max_score=("score", "max"),
          minutes_played=("minutes", "sum"),
      )
)
  • Use named aggregation para manter nomes limpos.
  • as_index=False conserva team como coluna (útil para merges e gráficos).
  • sort=False preserva a ordem original quando isso importa.

Múltiplas agregações em uma coluna

df.groupby("team", as_index=False).agg(
    score_mean=("score", "mean"),
    score_std=("score", "std"),
    score_count=("score", "size"),
)

Features por linha (transform)

transform mantém o tamanho original e devolve métricas de grupo para cada linha.

df["score_pct_of_team"] = (
    df["score"] / df.groupby("team")["score"].transform("sum")
)

Z-score por equipe:

df["score_z"] = (
    df.groupby("team")["score"]
      .transform(lambda s: (s - s.mean()) / s.std(ddof=0))
)

Quando usar transform:

  • Razões em relação ao total do grupo
  • Scores normalizados
  • Flags de grupo (ex.: rank, cumcount)

Quando apply vale a pena

apply é flexível, mas mais lento; use só quando agg/transform não bastam.

def top_n(group, n=2):
    return group.nlargest(n, "score")
 
top_players = df.groupby("team").apply(top_n, n=1).reset_index(drop=True)

Use apply se:

  • o número de linhas por grupo varia;
  • a lógica precisa de Python não vetorizado.

Grupos faltantes e ordenação

result = (
    df.groupby("team", dropna=False, sort=False)
      .agg(avg_score=("score", "mean"))
)
  • dropna=False mantém rótulos NaN.
  • sort=False evita reordenar—útil quando a ordem tem significado.

GroupBy com múltiplas chaves e índices

multi = (
    df.groupby(["team", "player"], as_index=False)
      .agg(score_mean=("score", "mean"))
)

Agrupando por níveis de índice:

df2 = df.set_index(["team", "player"])
df2.groupby(level="team")["score"].mean()

Armadilhas comuns

ProblemaCorreção
Forma inesperada (Series vs DataFrame)Use as_index=False ou depois reset_index().
Colunas duplicadas após mergeUse named aggregation para controlar nomes.
Lentidão por applyTroque por agg/transform ou métodos vetorizados.
Categorias sumindo na saídaMantenha observed=False (padrão) ou assegure categorias; dropna=False para NaN.

Dicas de exportação e visualização

  • Depois de agregar, ordene para apresentação: summary.sort_values("avg_score", ascending=False).
  • Para gráficos, faça pivot do resumo: summary.pivot(index="team", values="avg_score").

Guias relacionados


Em resumo

  • agg para resumos, transform para features por linha, apply com parcimônia.
  • Controle a forma com as_index e reset_index.
  • Gerencie ordem e rótulos ausentes com sort e dropna.
  • Prefira métodos vetorizados para manter pipelines rápidas.