Operações com Strings no Pandas: Limpeza Vetorizada de Texto
Updated on
Colunas de texto alimentam busca, segmentação e engenharia de atributos, mas muitos pipelines ainda iteram linha a linha ou misturam None/NaN, causando filtros quebrados e código lento.
- Problema: Caixa (maiúsculas/minúsculas), espaços em branco e correspondências parciais bagunçados tornam joins e análises pouco confiáveis.
- Agravante: Loops em Python linha a linha são lentos, e valores ausentes inconsistentes (
NonevsNaN) quebram comparações. - Solução: Use o dtype de string do pandas com métodos vetorizados
.str, controle explícito de regex e divisão/explosão segura para manter o processamento de texto rápido e previsível.
Want an AI agent that understands your pandas text cleaning and notebook context?
RunCell is a JupyterLab AI agent that can read your code, analyze DataFrames, understand notebook context, debug errors, and even generate & execute code for you. It works directly inside JupyterLab—no switching windows or copy-pasting.
👉 Try RunCell: runcell.dev (opens in a new tab)
Referência Rápida
| Objetivo | Método | Exemplo |
|---|---|---|
| Normalizar caixa/espaços em branco | .str.casefold(), .str.strip() | s.str.strip().str.casefold() |
| Substituição literal (rápida) | .str.replace(..., regex=False) | s.str.replace("-", " ", regex=False) |
| Extrair / localizar com regex | .str.extract(), .str.contains() | s.str.extract(r"(\d{4})") |
| Fazer split em colunas | .str.split(expand=True) | s.str.split("/", expand=True, n=2) |
| Fazer split em linhas | .str.split().explode() | df.assign(tag=df["tags"].str.split(",")).explode("tag") |
| Tamanho/contagens | .str.len(), .str.count() | s.str.count(r"\d") |
Comece com um Dtype de String Adequado
import pandas as pd
df["title"] = df["title"].astype("string[python]")- Usar o dtype
string(ou"string[pyarrow]"quando Arrow estiver instalado) mantém valores ausentes como<NA>, o que funciona bem com métodos.stre comparações. - Evite misturar objetos Python quando possível; colunas
objectsão mais lentas e menos consistentes para operações de texto.
Padrões Centrais de Limpeza
df["clean_name"] = (
df["name"]
.str.strip()
.str.replace(r"\s+", " ", regex=True)
.str.title()
)- Use
regex=Falsepara substituições literais simples, evitando interpretação acidental de regex e melhorando a velocidade. .str.normalize("NFKC")ajuda a unificar variantes Unicode ao comparar entradas de usuários.
Removendo ruído e aplicando caixa
df["search_key"] = df["product"].str.casefold().str.replace("-", " ", regex=False)casefold é mais robusto que lower para comparações de texto internacionalizadas.
Filtrando e Extraindo
# Verificações exatas de prefixo/sufixo
promo_rows = df[df["code"].str.startswith("PROMO", na=False)]
# contains com regex e tratamento seguro de NA
has_year = df["description"].str.contains(r"\b20\d{2}\b", regex=True, na=False)
# Grupos de captura em colunas
df[["year", "country"]] = df["id"].str.extract(r"(?P<year>\d{4})-(?P<country>[A-Z]{2})")- Defina
na=Falseao filtrar para tratar valores ausentes como não correspondentes. - Grupos nomeados em
extractcriam colunas legíveis sem necessidade de renomear depois.
Split, Expand e Explode
# Split em múltiplas colunas
df[["city", "state"]] = df["location"].str.split(",", n=1, expand=True)
# Split de uma coluna tipo lista em linhas
tags = df.assign(tag=df["tags"].str.split("|"))
tags = tags.explode("tag").assign(tag=lambda t: t["tag"].str.strip())- Use
expand=Truepara manter colunas alinhadas; prefiraexplodequando cada célula contém vários tokens que devem virar linhas. - Limpe os pedaços (
str.strip,str.casefold) antes de joins ou agregações.
Contando e Medindo Texto
df["word_count"] = df["abstract"].str.split().str.len()
df["digit_count"] = df["code"].str.count(r"\d").str.len()respeita<NA>; os resultados sãoInt64quando a entrada é dtypestring.- Combine com
fillna(0)se você precisar de inteiros “puros” para pipelines numéricos posteriores.
Dicas de Performance e Segurança
- Prefira métodos vetorizados
.strem vez deapply(lambda ...); eles são mais rápidos e cientes de NA. - Especifique
regex=Falsequando você só precisar de substituições literais para evitar o custo do regex. - Para colunas de texto grandes, considere
string[pyarrow]para reduzir memória e acelerar operações comuns (requerpyarrowinstalado). - Normalize chaves intermediárias uma única vez (strip + casefold) e reutilize-as para joins ou deduplicação em vez de recalculá-las.
Operações vetorizadas com strings mantêm a limpeza de texto concisa e performática. Combine-as com pandas-data-cleaning para verificações de qualidade mais amplas e use com pandas-merge-join quando as chaves normalizadas estiverem prontas para joins confiáveis.