Texto e categorias em pandas
Normalizar strings, extrair campos, filtrar texto e usar categorias ordenadas.
Uma coluna de cidade pode conter "Porto", " porto " e "PORTO". São três strings diferentes, mas podem identificar a mesma cidade. Normalizar texto exige uma regra sobre o que deve ser tratado como equivalente.
Métodos de strings numa coluna
import pandas as pd
cidades = pd.Series([" Porto ", "BRAGA", None, "porto"], dtype="string")
limpas = cidades.str.strip().str.lower()
print(limpas.to_list())
print(limpas.str.contains("port", regex=False, na=False).to_list())
print(limpas.value_counts(dropna=False).to_string())Dados de entrada
As strings conhecidas ficam porto, braga e porto; a ausência mantém-se. O filtro é [True, False, False, True]. na=False define que as linhas sem texto não são selecionadas.
A propriedade .str aplica métodos de texto aos elementos da Series. str.len() calcula o comprimento, str.startswith() e str.endswith() testam extremos. str.split(";", expand=True) divide campos e devolve colunas separadas.
Texto literal e expressões regulares
str.contains pode interpretar o padrão como uma expressão regular. Um ponto numa expressão regular significa normalmente “qualquer carácter”, não um ponto literal. Para procurar texto literal, indica regex=False.
str.replace também permite escolher o modo. Escreve o argumento quando a distinção é relevante, porque os valores por defeito mudaram em versões anteriores.
codigos = pd.Series(["PT-001", "PT-014", "sem código"], dtype="string")
extraidos = codigos.str.extract(r"^PT-(\d{3})$", expand=False)
O padrão exige o prefixo PT-, exatamente três algarismos e nenhum texto extra. O resultado conserva os algarismos como texto, incluindo zeros iniciais; a linha sem correspondência fica em falta. Os parênteses definem o grupo capturado. Se não estudaste expressões regulares, começa pela separação com um delimitador e só usa um padrão quando a estrutura do campo o exige.
Categorias
Uma coluna categórica representa valores de um conjunto de categorias. Pode reduzir repetição e permitir uma ordem explícita. Converter uma string para categoria não corrige erros ortográficos.
import pandas as pd
tipo = pd.CategoricalDtype(categories=["baixo", "médio", "alto"], ordered=True)
prioridades = pd.Series(["alto", "baixo", "médio", "baixo"], dtype=tipo)
print(prioridades.sort_values().to_list())
print((prioridades > "médio").to_list())Dados de entrada
A ordem é baixo, baixo, médio, alto. Só a primeira observação original é maior que médio. Uma ordenação alfabética não expressaria essa hierarquia.
serie.cat.categories lista categorias possíveis. .cat.codes mostra códigos internos, mas esses códigos não são medidas numéricas. A diferença entre os códigos de baixo e alto não representa uma distância quantitativa.
Categorias não observadas e ausências
Uma categoria pode existir no tipo sem aparecer nos dados. Ao agrupar categorias, indica observed=True para considerar apenas combinações observadas ou observed=False quando queres também categorias definidas sem observações. O valor por defeito depende da versão.
Um valor fora das categorias declaradas pode transformar-se em ausência durante a conversão. Confere as strings antes e o número de nulos depois. Acrescentar uma categoria com .cat.add_categories define um valor possível; não cria observações dessa categoria.
Exercícios
Procurar um ponto
Queres selecionar strings que contêm um ponto literal. Que argumento torna esse significado explícito em str.contains?
Primeira pista
Mais uma pista
Se não precisas de expressões regulares, desliga a sua interpretação.
Ver solução
Usa s.str.contains(”.”, regex=False, na=False), se ausências não devem ser selecionadas.
- regex=False. Trata o padrão como texto literal.
- regex=True com padrão ".". O ponto corresponde normalmente a qualquer carácter.
- na=True. Decide o resultado dos valores ausentes, não o significado do padrão.
Erros frequentes
Confundir a política de nulos com a interpretação do padrão.
Dar significado à ordenação
Queres ordenar baixo, médio e alto pela prioridade. Explica por que ordenar as strings não basta e como definir a ordem.
Primeira pista
Mais uma pista
Ver solução
Cria pd.CategoricalDtype([“baixo”, “médio”, “alto”], ordered=True), converte a Series e ordena-a. A ordem passa a expressar o contrato do problema.
Confere a tua resposta:
- Defini as categorias na ordem baixo, médio, alto.
- Usei ordered=True.
- Distingui códigos internos de uma medida numérica.
Erros frequentes
Usar códigos internos como se a diferença numérica representasse a distância entre prioridades.