Operaciones con cadenas en pandas: Limpieza de texto vectorizada
Updated on
Las columnas de texto impulsan la búsqueda, la segmentación y el feature engineering, pero muchos pipelines aún iteran por filas o mezclan None/NaN, lo que provoca filtros rotos y código lento.
- Problema: Mayúsculas/minúsculas desordenadas, espacios en blanco y coincidencias parciales hacen que los joins y el análisis sean poco fiables.
- Agitar: Los bucles fila por fila en Python son lentos y los valores faltantes incoherentes (
NonevsNaN) rompen las comparaciones. - Solución: Usa el tipo de datos string de pandas con métodos vectorizados
.str, control explícito de regex y división/explosión segura para mantener el procesamiento de texto rápido y predecible.
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)
Referencia rápida
| Objetivo | Método | Ejemplo |
|---|---|---|
| Normalizar mayúsculas/minúsculas/espacios | .str.casefold(), .str.strip() | s.str.strip().str.casefold() |
| Reemplazo literal (rápido) | .str.replace(..., regex=False) | s.str.replace("-", " ", regex=False) |
| Extraer / buscar con regex | .str.extract(), .str.contains() | s.str.extract(r"(\d{4})") |
| Dividir en columnas | .str.split(expand=True) | s.str.split("/", expand=True, n=2) |
| Dividir en filas | .str.split().explode() | df.assign(tag=df["tags"].str.split(",")).explode("tag") |
| Longitud/contadores | .str.len(), .str.count() | s.str.count(r"\d") |
Empieza con un tipo de datos string adecuado
import pandas as pd
df["title"] = df["title"].astype("string[python]")- Usar el tipo de datos
string(o"string[pyarrow]"cuando Arrow está instalado) mantiene los valores faltantes como<NA>, lo que funciona bien con los métodos.stry las comparaciones. - Evita mezclar objetos de Python cuando sea posible; las columnas
objectson más lentas y menos consistentes para operaciones de texto.
Patrones básicos de limpieza
df["clean_name"] = (
df["name"]
.str.strip()
.str.replace(r"\s+", " ", regex=True)
.str.title()
)- Usa
regex=Falsepara reemplazos literales simples, para evitar una interpretación accidental como regex y mejorar el rendimiento. .str.normalize("NFKC")ayuda a unificar variantes Unicode cuando comparas entradas de usuarios.
Eliminar ruido y unificar mayúsculas/minúsculas
df["search_key"] = df["product"].str.casefold().str.replace("-", " ", regex=False)casefold es más robusto que lower para comparaciones de texto internacionalizadas.
Filtrado y extracción
# Comprobaciones exactas de prefijo/sufijo
promo_rows = df[df["code"].str.startswith("PROMO", na=False)]
# Búsqueda con regex con manejo seguro de NA
has_year = df["description"].str.contains(r"\b20\d{2}\b", regex=True, na=False)
# Grupos de captura a columnas
df[["year", "country"]] = df["id"].str.extract(r"(?P<year>\d{4})-(?P<country>[A-Z]{2})")- Configura
na=Falseal filtrar para tratar los valores faltantes como no coincidencias. - Los grupos con nombre en
extractcrean columnas legibles sin renombrar después.
Split, expand y explode
# Dividir en múltiples columnas
df[["city", "state"]] = df["location"].str.split(",", n=1, expand=True)
# Dividir una columna tipo lista en filas
tags = df.assign(tag=df["tags"].str.split("|"))
tags = tags.explode("tag").assign(tag=lambda t: t["tag"].str.strip())- Usa
expand=Truepara mantener columnas alineadas; prefiereexplodecuando cada celda contiene varios tokens que deben convertirse en filas. - Limpia las partes (
str.strip,str.casefold) antes de hacer joins o agregaciones.
Contar y medir texto
df["word_count"] = df["abstract"].str.split().str.len()
df["digit_count"] = df["code"].str.count(r"\d").str.len()respeta<NA>; los resultados sonInt64cuando la entrada es tipostring.- Combínalo con
fillna(0)si necesitas enteros estándar para pipelines numéricos posteriores.
Consejos de rendimiento y seguridad
- Prioriza los métodos vectorizados
.strsobreapply(lambda ...); son más rápidos y conscientes de NA. - Especifica
regex=Falsecuando solo necesites reemplazos literales para evitar la sobrecarga de regex. - Para columnas de texto grandes, considera
string[pyarrow]para reducir memoria y acelerar operaciones comunes (requiere tenerpyarrowinstalado). - Normaliza las claves intermedias una sola vez (strip + casefold) y reutilízalas para joins o deduplicación en lugar de recalcularlas.
Las operaciones vectorizadas con cadenas mantienen la limpieza de texto concisa y eficiente. Combínalas con pandas-data-cleaning para verificaciones de calidad más amplias y con pandas-merge-join cuando las claves normalizadas estén listas para joins fiables.