Skip to content

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 (None vs NaN) 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

ObjetivoMétodoEjemplo
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 .str y las comparaciones.
  • Evita mezclar objetos de Python cuando sea posible; las columnas object son 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=False para 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=False al filtrar para tratar los valores faltantes como no coincidencias.
  • Los grupos con nombre en extract crean 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=True para mantener columnas alineadas; prefiere explode cuando 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 son Int64 cuando la entrada es tipo string.
  • 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 .str sobre apply(lambda ...); son más rápidos y conscientes de NA.
  • Especifica regex=False cuando 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 tener pyarrow instalado).
  • 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.