Criar faixas com pd.cut

Transformar uma variável quantitativa em faixas (intervalos) para contar, cruzar e montar histogramas.
Operações com pandasOperações com pandasAula 7← voltar ao mapa
Na prova · extra pd.cut não está no formulário e não é o foco da prova. 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

pd.cut(coluna, bins=...) coloca cada valor de uma variável quantitativa dentro de uma faixa; o resultado é uma variável qualitativa ordinal que pode ser contada, cruzada e agrupada, e é a tabela que está por trás de um histograma.

A ideia

Na Aula 5, o Exercício 1 pedia uma tabela de frequências da RENDA com .value_counts(). O resultado foi inútil: quase todo cliente tem uma renda diferente, então cada valor aparece uma ou duas vezes. Com uma variável contínua, contar valores exatos não resume nada.

A saída é agrupar valores próximos em faixas: 0,5 a 3,5 mil, 3,5 a 6,5 mil, e assim por diante. Depois disso, a faixa é uma variável qualitativa ordinal, e todas as ferramentas de qualitativas voltam a funcionar: tabela de frequências, tabela cruzada, groupby. E a contagem por faixa é exatamente a altura das barras do histograma da Aula 7.

Como ler um intervalo. O pandas escreve as faixas como (3.5, 6.5]: o parêntese quer dizer aberto (o 3,5 fica de fora) e o colchete quer dizer fechado (o 6,5 entra). Por padrão, as faixas são abertas à esquerda e fechadas à direita. Três consequências práticas:

  • um valor exatamente igual ao limite inferior da primeira faixa fica fora de todas as faixas (vira NaN). Por isso, na Aula 7, as faixas da renda começam em 0,5, abaixo da menor renda (0,6);
  • include_lowest=True inclui o limite inferior na primeira faixa;
  • right=False inverte tudo: faixas [a, b), fechadas à esquerda e abertas à direita.

Para faixas de mesma largura, np.arange(início, fim, passo) monta a lista de limites (o fim não entra, como no range).

No código

São 65 valores diferentes para 82 clientes. Agora com faixas de largura 3, começando em 0,5, como no Exercício 2 da Aula 7:

A tabela diz, por exemplo, que 25 clientes ganham mais de 3,5 e até 6,5 mil reais. O histograma com os mesmos limites desenha essas contagens como barras:

O cuidado com o limite inferior. A menor idade da base é 18 anos. Com faixas que começam em 18:

Sem include_lowest, o cliente de 18 anos some (a primeira faixa é (18, 30]); com ele, a faixa vira (17.999, 30.0] e ninguém se perde. Com right=False, as faixas ficam [a, b), e o limite de cima precisa passar da maior idade (60):

Com a faixa pronta, dá para cruzar com o plano:

Entre os clientes de até 30 anos, 40,6% estão no plano A; entre os de 45 a 60, 70,0%. A idade também parece ajudar na recomendação.

Armadilhas comuns

  • Primeira faixa começando no menor valor. Ele vira NaN e some das contagens. Comece abaixo do mínimo ou use include_lowest=True, e confira com .isna().sum().
  • Última faixa terminando antes do máximo. Valores acima do último limite também viram NaN. Com np.arange, lembre que o fim não entra: np.arange(0.5, 22, 3) para em 21,5.
  • Ler (a, b] como se incluísse o a. O parêntese exclui, o colchete inclui.
  • Faixas de larguras diferentes no histograma de contagem. Faixas mais largas juntam mais gente e parecem maiores. Com larguras diferentes, use density=True no histograma (Exercício 1 da Aula 7).
  • Esquecer que o resultado é ordinal. pd.cut já devolve uma categoria ordenada; use value_counts(sort=False) para ver as faixas em ordem.

O argumento labels troca os intervalos por nomes: pd.cut(dados['IDADE'], bins=[18, 30, 45, 60], include_lowest=True, labels=['até 30', '31 a 45', '46 a 60']). Na lista da Aula 9, o Exercício 9 usa pd.cut com right=False para criar faixas de 3 em 3 anos de empresa e, no Exercício 10, compara salários por faixa com groupby.

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

Divida a idade do Titanic nas faixas [0, 12, 18, 60, 80] e conte quantos passageiros há em cada faixa, na ordem das faixas. (Passageiros sem idade registrada ficam de fora.)

bins recebe os limites das faixas, do menor para o maior.

faixa_idade = pd.cut(titanic['Age'], bins=[0, 12, 18, 60, 80])
contagem = faixa_idade.value_counts(sort=False)
contagem

Exercício 2

Dê nomes às faixas com labels e calcule a probabilidade de sobreviver entre as crianças: filtre as linhas da faixa e tire a média de Survived.

O rótulo tem de ser escrito igual ao de labels, com cedilha e acento.

titanic['FAIXA'] = pd.cut(titanic['Age'], bins=[0, 12, 18, 60, 80],
                          labels=['criança', 'adolescente', 'adulto', 'idoso'])
p_s_crianca = titanic.loc[titanic['FAIXA'] == 'criança', 'Survived'].mean()
p_s_crianca

Exercício 3

Com bins=[0, 12, 18, 60, 80], em que faixa cai uma criança de exatamente 12 anos: 'criança' ou 'adolescente'?

Por padrão, pd.cut inclui o limite da direita de cada faixa.

print(pd.cut([12], bins=[0, 12, 18, 60, 80], labels=['criança', 'adolescente', 'adulto', 'idoso']))
resposta = 'criança'
resposta

Comandos e documentação oficial

Pontes com o outro lado do mapa

Este tópico aparece nestas paradas da revisão guiada, em que cada ponte vira um exercício resolvido pelos dois caminhos:

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.