7 min de leitura
#5 - Agrupando e Agregando Dados com groupby()
Como usar o groupby() do Pandas para agrupar dados por categoria e calcular agregações com o padrão split-apply-combine, incluindo o método agg().
No post anterior você aprendeu a filtrar um DataFrame pra ficar só com as linhas que interessam. O próximo passo natural, depois de filtrar, é resumir: em vez de olhar linha por linha, você quer respostas como “qual a média de vendas por região?” ou “quantos produtos cada categoria tem?”. É exatamente pra isso que existe o groupby().
O padrão split-apply-combine
O groupby() segue uma lógica em três etapas, conhecida como split-apply-combine:
- Split (dividir): o DataFrame é dividido em grupos, com base nos valores de uma ou mais colunas;
- Apply (aplicar): uma função é aplicada separadamente a cada grupo (uma soma, uma média, uma contagem…);
- Combine (combinar): os resultados de cada grupo são reunidos de volta numa única estrutura.
Na prática, você quase nunca pensa nessas três etapas separadamente — o Pandas cuida disso internamente. Mas ter esse modelo mental em mente ajuda a entender o que está acontecendo por trás de cada .groupby(...).
Agrupando com groupby()
Vamos usar como exemplo um DataFrame com vendas de produtos em diferentes regiões:
import pandas as pd
dados = {
"regiao": ["Sul", "Sudeste", "Sul", "Nordeste", "Sudeste", "Nordeste", "Sul"],
"produto": ["Notebook", "Notebook", "Mouse", "Mouse", "Teclado", "Notebook", "Teclado"],
"unidades": [5, 12, 30, 18, 22, 7, 15],
"receita": [16000, 38400, 2670, 1602, 3300, 22400, 2250]
}
df = pd.DataFrame(dados)
Exemplo 1 - criando o objeto GroupBy
grupos = df.groupby("regiao")
print(grupos)
A saída é algo como:
<pandas.core.groupby.generic.DataFrameGroupBy object at 0x7f2a1c0b5d90>
Repare que groupby() sozinho não devolve uma tabela — devolve um objeto DataFrameGroupBy, que guarda a informação de como os dados foram divididos, mas só calcula alguma coisa quando você chama um método de agregação em cima dele.
Exemplo 2 - contando linhas por grupo
print(grupos.size())
regiao
Nordeste 2
Sudeste 2
Sul 3
dtype: int64
.size() conta quantas linhas caíram em cada grupo, incluindo linhas com valores nulos. Se você quiser contar valores não-nulos por coluna, use .count() no lugar.
Agregando com funções estatísticas
Com os grupos formados, dá pra aplicar qualquer função estatística — ela é calculada separadamente pra cada grupo.
Exemplo 3 - média por grupo
print(df.groupby("regiao")["receita"].mean())
regiao
Nordeste 12001.0
Sudeste 20850.0
Sul 6973.333333
dtype: float64
Exemplo 4 - soma de todas as colunas numéricas
Sem selecionar uma coluna específica, a agregação é aplicada a todas as colunas numéricas do DataFrame:
print(df.groupby("regiao")[["unidades", "receita"]].sum())
unidades receita
regiao
Nordeste 25 24002
Sudeste 34 41700
Sul 50 20920
Outras agregações comuns funcionam do mesmo jeito: .max(), .min(), .median(), .std().
Agrupando por múltiplas colunas
Pra cruzar mais de uma dimensão ao mesmo tempo, passe uma lista de nomes de coluna pro groupby():
Exemplo 5 - região e produto juntos
print(df.groupby(["regiao", "produto"])["receita"].sum())
regiao produto
Nordeste Mouse 1602
Notebook 22400
Sudeste Notebook 38400
Teclado 3300
Sul Mouse 2670
Notebook 16000
Teclado 2250
Name: receita, dtype: int64
O resultado ganha um índice em dois níveis (um MultiIndex): primeiro a região, depois o produto dentro dela.
Múltiplas agregações com agg()
Calcular só uma estatística por vez é limitado — o método .agg() (abreviação de aggregate) permite pedir várias de uma vez, ou até funções diferentes por coluna.
Exemplo 6 - várias funções na mesma coluna
print(df.groupby("regiao")["receita"].agg(["sum", "mean", "max"]))
sum mean max
regiao
Nordeste 24002 12001.000000 22400
Sudeste 41700 20850.000000 38400
Sul 20920 6973.333333 16000
Exemplo 7 - uma função diferente por coluna
Passando um dicionário, cada coluna recebe sua própria lista de agregações:
resultado = df.groupby("regiao").agg({
"unidades": "sum",
"receita": ["mean", "max"]
})
print(resultado)
unidades receita
sum mean max
regiao
Nordeste 25 12001.000000 22400
Sudeste 34 20850.000000 38400
Sul 50 6973.333333 16000
Nota: o
.agg()também aceita funções personalizadas, inclusivelambdas — por exemplo,df.groupby("regiao")["receita"].agg(lambda x: x.max() - x.min())calcula a amplitude (máximo menos mínimo) de receita em cada região.
Iterando e acessando um grupo específico
Exemplo 8 - percorrendo cada grupo com um for
O objeto GroupBy é iterável: cada iteração devolve uma tupla com o nome do grupo e o DataFrame correspondente.
for regiao, grupo in df.groupby("regiao"):
print(f"Região: {regiao} — total de linhas: {len(grupo)}")
Região: Nordeste — total de linhas: 2
Região: Sudeste — total de linhas: 2
Região: Sul — total de linhas: 3
Exemplo 9 - buscando um grupo específico com get_group()
Se você já sabe qual grupo quer, não precisa iterar por todos — .get_group() busca direto:
print(df.groupby("regiao").get_group("Sul"))
regiao produto unidades receita
0 Sul Notebook 5 16000
2 Sul Mouse 30 2670
6 Sul Teclado 15 2250
Com groupby() e agg() você já consegue transformar uma tabela de linhas soltas em resumos por categoria — a base de praticamente qualquer relatório ou dashboard. No próximo post, vamos ver o que fazer quando essa informação está espalhada em mais de um DataFrame: como combinar tabelas diferentes com merge(), join() e concat().
Fonte adaptada: Pandas - GroupBy, Pandas - Aggregations
Comentários