# Texto e categorias em pandas

Normalizar strings, extrair campos, filtrar texto e usar categorias ordenadas.

Página: https://resumos.rgo.pt/cadeiras/ct-iadp/texto-categorias/

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

```python
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())
```

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.

```python
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())
```

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

O ponto tem significado próprio numa expressão regular.

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.

[Voltar à explicação](https://resumos.rgo.pt/cadeiras/ct-iadp/texto-categorias/#texto-literal-e-express%C3%B5es-regulares)

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

A ordem alfabética não é a ordem de prioridade.

Mais uma pista

Usa um CategoricalDtype com categorias explícitas.

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.

[Voltar à explicação](https://resumos.rgo.pt/cadeiras/ct-iadp/texto-categorias/#categorias)
