Variáveis qualitativas no pandas (category)

Avisar o pandas que uma coluna é qualitativa, dar nomes aos rótulos e definir a ordem.
Operações com pandasOperações com pandasAula 3 Aula 4 Aula 5← voltar ao mapa
Na prova · apoio A prova costuma trazer pronto o código que transforma em category e define a ordem: é só rodar sem alterar. 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

O pandas não sabe que PLANO = 1 significa “plano A”, nem que “Satisfeito” vem depois de “Indiferente”: você avisa com .astype('category'), dá nomes com .cat.rename_categories() e define a ordem com pd.Categorical(..., ordered=True).

A ideia

Ao ler um arquivo, o pandas só enxerga como os dados estão guardados: números (int64, float64) ou texto (object). Ele não conhece a natureza estatística das variáveis. Na Empresa de TV (Aula 3), PLANO e EC vêm como números (1, 2, 3) e SATISFACAO vem como texto. Cabe a quem analisa classificar cada variável (veja Tipos de variáveis) e ajustar a coluna.

Por que isso importa?

  • Números que são códigos enganam. A média de PLANO sai como 1,44, um número que não significa nada.
  • Tabelas e gráficos saem na ordem certa. Uma variável ordinal (satisfação, escolaridade) precisa aparecer do menor para o maior nível, e não em ordem alfabética.
  • Probabilidade fica mais legível. Com rótulos como 'Yes'/'No' no Titanic (Aula 4), a tabela de frequências já mostra \(P(S)\) e \(P(S^c)\) com nome.

O caminho da Aula 3 tem quatro passos: converter (astype('category')), ver os rótulos (.cat.categories), renomear (.cat.rename_categories) e definir a ordem (pd.Categorical). Todos devolvem uma coluna nova, então é preciso guardar o resultado na própria coluna (dados['X'] = ...).

No código

Converter, ver e renomear uma variável nominal:

O .cat só existe depois da conversão. Tentar renomear uma coluna que ainda é número dá erro:

Definir a ordem de uma variável ordinal. Veja a SATISFACAO em três momentos: como texto, como categoria sem ordem e como categoria ordenada.

Aqui está o ponto que mais confunde: sort=False em .value_counts() não significa “ordem natural”. Significa “não ordene por frequência; use a ordem que a coluna já tem”. Em uma coluna de texto, essa ordem é a de aparecimento na base; em uma categoria sem ordem definida, é a alfabética. Só depois do pd.Categorical com a lista de níveis a tabela sai de “Muito Insatisfeito” a “Muito Satisfeito”.

Com ordered=True, as comparações passam a fazer sentido:

Cerca de 47,6% dos clientes estão pelo menos satisfeitos. Um erro silencioso: se a lista de níveis tiver um nome escrito diferente do que está na base, os valores viram NaN sem aviso.

Vinte clientes sumiram só por causa de uma letra minúscula.

Armadilhas comuns

  • Esquecer de guardar. dados['PLANO'].astype('category') sozinho não muda nada. Escreva dados['PLANO'] = dados['PLANO'].astype('category').
  • Usar .cat antes de converter. O erro Can only use .cat accessor with a 'category' dtype pede o astype('category') antes.
  • Nomes diferentes na lista de categories. Maiúsculas, acentos e espaços precisam bater exatamente com a base; senão viram NaN. Depois do pd.Categorical, confira com .value_counts(sort=False, dropna=False).
  • Achar que sort=False ordena pela ordem natural. Só com a ordem definida em pd.Categorical.
  • ordered=True em variável nominal. Estado civil e plano não têm ordem natural; use ordered=False (a ordem da lista serve só para a apresentação).

Com Survived como categoria de rótulos 'Yes' e 'No' e ordem ['Yes', 'No'], dados['Survived'].value_counts(normalize=True, sort=False) mostra primeiro \(P(S)\) e depois \(P(S^c)\), sempre na mesma ordem, e tabela['Yes'] pega a probabilidade pelo nome. Foi exatamente a preparação da base do Titanic na Aula 4, antes do Teorema de Bayes.

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

Transforme Pclass do Titanic em variável qualitativa e renomeie os rótulos: 1 vira '1st', 2 vira '2nd' e 3 vira '3rd'.

.cat.rename_categories só funciona depois de .astype('category').

titanic['Pclass'] = titanic['Pclass'].astype('category')
titanic['Pclass'] = titanic['Pclass'].cat.rename_categories({1: '1st', 2: '2nd', 3: '3rd'})
titanic['Pclass']

Exercício 2

A classe da passagem é ordinal. Redefina com pd.Categorical na ordem 1st, 2nd, 3rd, avisando que há ordem. Com a ordem, dá para comparar: qual a proporção de passageiros da 1ª ou da 2ª classe (<= '2nd')?

Sem ordered=True, o pandas não sabe que 1st vem antes de 2nd.

titanic['Pclass'] = pd.Categorical(titanic['Pclass'], categories=['1st', '2nd', '3rd'], ordered=True)
p_ate_2a = (titanic['Pclass'] <= '2nd').mean()
p_ate_2a

Exercício 3

Na Empresa de TV, classifique ESCOLARIDADE e EC (estado civil) como 'nominal' ou 'ordinal'.

Ordinal: as categorias têm uma ordem natural.

tipos = {'ESCOLARIDADE': 'ordinal', 'EC': 'nominal'}
tipos

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.