Resumir por grupo com groupby

Calcular o mesmo resumo de uma variável quantitativa para cada categoria de uma qualitativa.
Operações com pandasOperações com pandasAula 5 Aula 7← voltar ao mapa
Na prova · apoio Costuma vir pronto, como groupby(…).describe(); o que conta é ler e interpretar a tabela. Está no formulário. Guia da prova

Os códigos desta página rodam no navegador, mas não sozinhos: clique em Run Code em cada bloco, de cima para baixo.

DicaEm uma frase

dados.groupby('grupo', observed=False)['variável'].describe() separa a base pelas categorias de uma variável qualitativa e calcula o mesmo resumo da variável quantitativa dentro de cada grupo, em uma linha só.

A ideia

Na Aula 5, a Empresa de TV queria saber se a renda ajuda a recomendar um plano. O primeiro caminho foi manual: filtrar os clientes do plano A em dados_a, os do plano B em dados_b e calcular .describe() em cada um. Funciona, mas com três ou cinco categorias vira um trabalho repetitivo.

O groupby faz isso por você, em três passos: separa as linhas por categoria, aplica o resumo em cada pedaço e junta os resultados em uma tabela, com uma linha por grupo.

Pense no groupby como o primo quantitativo da tabela cruzada: o crosstab cruza duas qualitativas; o groupby descreve uma quantitativa dentro de cada categoria de uma qualitativa. É o que o mapa mental da análise exploratória resume assim: qualitativa × quantitativa → .groupby(by=...). Nos dois casos, a ideia é comparar a distribuição de uma variável condicionada a um grupo.

O argumento observed. Quando a coluna de grupo é uma categoria, pode existir uma categoria sem nenhuma observação em algum grupo (por exemplo, nenhum cliente do plano B está “Muito Satisfeito”). Com observed=False, o pandas mantém todas as categorias possíveis, mesmo as vazias; com observed=True, só as que aparecem na amostra. Nas aulas usamos observed=False, que reforça a ideia de que as categorias são definidas pelo problema, e escrevemos o argumento explicitamente para não receber avisos.

No código

O caminho manual, com filtro, para um grupo:

O mesmo resumo para todos os grupos de uma vez:

Leia linha por linha: a renda média é de 10,422 mil reais no plano A e de 5,689 mil no plano B; as medianas são 10,35 e 5,15. Três quartos dos clientes do plano B ganham até 6,375 mil, menos do que a mediana do plano A. A renda parece ajudar a recomendar o plano, e o boxplot mostra a mesma coisa em forma de gráfico:

Agrupando por duas variáveis e contando os clientes, aparece o efeito do observed:

Com observed=False, o plano B mostra “Muito Satisfeito” com 0 clientes; com observed=True, essa linha some. Um zero também é informação: nenhum cliente do plano B está muito satisfeito.

O erro mais comum é esquecer de escolher a coluna. Sem ['RENDA'], o pandas tenta tirar a média de todas as colunas, inclusive as de texto:

Armadilhas comuns

  • Não escolher a coluna. dados.groupby('PLANO').mean() tenta resumir colunas de texto e dá TypeError. Escreva dados.groupby('PLANO', observed=False)['RENDA'].mean().
  • Agrupar por uma variável quantitativa. dados.groupby('IDADE') cria um grupo para cada idade. Primeiro crie faixas com pd.cut e agrupe pelas faixas, como no Exercício 10 da lista da Aula 9.
  • Omitir o observed. Com colunas categóricas, o pandas avisa que o comportamento padrão vai mudar. Escreva observed=False (ou True) de propósito.
  • Comparar só as médias. A média é sensível a valores extremos. Olhe também mediana e quartis no .describe() e confira o formato no boxplot (veja Simetria e assimetria).

A média da renda dentro do plano A é uma média condicional: é a renda média dado que o cliente é do plano A. Quando a variável de grupo tem só dois rótulos e a variável resumida vale 0 ou 1 (como Survived no Titanic), dados.groupby('Sex')['Survived'].mean() devolve direto \(P(S \mid F)\) e \(P(S \mid M)\), as mesmas probabilidades da probabilidade condicional e do classificador da Aula 4.

Exercícios aqui na página

Complete os ______ e clique em Run Code: a correção aparece logo abaixo. Use Show Hint para uma dica e Show Solution para ver uma resolução. O Python roda no seu navegador; na primeira vez ele leva alguns segundos para carregar.

Exercício 1

Na Empresa de TV, calcule a idade média de cada estado civil (EC).

Depois do groupby, os colchetes escolhem a coluna a ser resumida.

idade_ec = tv.groupby(by='EC', observed=False)['IDADE'].mean()
idade_ec

Exercício 2

No Titanic, Survived vale 0 ou 1. A média de Survived em cada classe é a proporção de sobreviventes nela, ou seja, \(P(S \mid \text{classe})\). Calcule para as três classes.

É o mesmo número que a tabela cruzada com normalize='index' daria.

p_s_classe = titanic.groupby(by='Pclass')['Survived'].mean()
p_s_classe

Exercício 3

Pelo resultado anterior, qual classe tem a maior probabilidade de sobrevivência? Escreva '1', '2' ou '3'.

Os rótulos das linhas são as classes.

print(p_s_classe)
classe = '1'
classe

Comandos e documentação oficial

formulário o comando está no formulário que você pode consultar na prova.

Pratique

As listas novas de revisão abrem no Google Colab (use Arquivo → Salvar uma cópia no Drive). As listas das aulas estão no Blackboard, na pasta de cada aula.