certmundo.
es‑mx

6 min de lectura

¿Cómo limpiar datos sucios con pandas?

Limpiar datos sucios con pandas significa identificar y corregir valores nulos, duplicados y tipos de dato incorrectos antes de hacer cualquier análisis.

Los datos reales siempre tienen errores. Un archivo exportado del SAT, del IMSS o de un sistema de ventas de Liverpool casi nunca llega perfecto. Aprender a limpiarlos es la habilidad más importante en el análisis de datos.

¿Qué es un dato "sucio"?

Un dato sucio es cualquier valor que impide un análisis correcto. Existen tres tipos principales:

Tipo de problema Ejemplo real
Valor nulo Una celda vacía en la columna salario
Duplicado El mismo empleado registrado dos veces
Tipo incorrecto La columna precio guardada como texto, no como número

Cada tipo requiere una técnica distinta. Las siguientes secciones cubren cada una paso a paso.


Cómo detectar valores nulos

Un valor nulo es una celda sin información. En pandas se representa como NaN (Not a Number).

Usa .isnull().sum() para contar los nulos por columna:

import pandas as pd

df = pd.read_csv("empleados_bimbo.csv", encoding="latin-1")
print(df.isnull().sum())

Resultado:

nombre        0
departamento  3
salario       7
fecha_alta    1
dtype: int64

Eso significa que la columna salario tiene 7 celdas vacías. Antes de calcular promedios o totales, debes decidir qué hacer con esas celdas.

Opción 1: Eliminar filas con nulos

Usa .dropna() para eliminar cualquier fila que tenga al menos un valor nulo:

df_limpio = df.dropna()
print(df_limpio.shape)

Esta opción funciona bien cuando los nulos son pocos y no afectan el análisis.

Opción 2: Rellenar nulos con un valor

Usa .fillna() para sustituir los nulos por un valor específico:

# Rellenar salarios nulos con el promedio del grupo
promedio_salario = df["salario"].mean()
df["salario"] = df["salario"].fillna(promedio_salario)

En un contexto de FEMSA, si tienes registros de vendedores sin salario capturado, rellenar con el promedio evita perder esas filas.

Opción 3: Rellenar con el valor anterior

Usa method="ffill" (forward fill) cuando los datos son secuenciales, como fechas de pedidos:

df["fecha_entrega"] = df["fecha_entrega"].fillna(method="ffill")

Cómo eliminar duplicados

Un duplicado es una fila idéntica o casi idéntica a otra. Ocurre cuando dos sistemas registran el mismo evento, o cuando alguien importa un archivo dos veces.

Usa .duplicated() para detectarlos:

print(df.duplicated().sum())

Si el resultado es mayor que cero, tienes filas repetidas. Elimínalas con .drop_duplicates():

df = df.drop_duplicates()
print(df.shape)

Duplicados parciales

A veces solo quieres verificar si hay duplicados en una columna específica. Por ejemplo, en una base de clientes de Mercado Libre, el campo id_cliente no debe repetirse:

duplicados_id = df[df.duplicated(subset=["id_cliente"], keep=False)]
print(duplicados_id)

El parámetro keep=False muestra todas las filas duplicadas, no solo la segunda. Eso te ayuda a revisar cuál versión conservar.


Cómo corregir tipos de dato incorrectos

Un tipo de dato incorrecto ocurre cuando pandas interpreta mal una columna. La columna precio puede quedar como object (texto) si tiene comas o signos de peso.

Verifica los tipos con .dtypes:

print(df.dtypes)

Resultado típico con datos sucios:

producto      object
precio        object
cantidad      object
fecha_venta   object
dtype: object

Todas las columnas quedaron como texto. Eso impide hacer sumas o promedios.

Convertir texto a número

Usa pd.to_numeric() para convertir una columna a número. El parámetro errors="coerce" convierte los valores que no se pueden transformar en NaN, en lugar de generar un error:

df["precio"] = pd.to_numeric(df["precio"], errors="coerce")
df["cantidad"] = pd.to_numeric(df["cantidad"], errors="coerce")

Limpiar texto antes de convertir

Si la columna precio contiene valores como "$1,250" o "1250.50 MXN", primero debes limpiar el texto:

df["precio"] = df["precio"].str.replace("$", "", regex=False)
df["precio"] = df["precio"].str.replace(",", "", regex=False)
df["precio"] = pd.to_numeric(df["precio"], errors="coerce")

Después de estos tres pasos, la columna precio queda como número flotante y puedes operar con ella.

Convertir texto a fecha

Usa pd.to_datetime() para columnas de fechas:

df["fecha_venta"] = pd.to_datetime(df["fecha_venta"], dayfirst=True, errors="coerce")

El parámetro dayfirst=True es importante en México, donde las fechas se escriben como DD/MM/AAAA y no como MM/DD/AAAA.


Ejemplo completo: limpieza de ventas de una tienda Liverpool

Supón que tienes un archivo ventas_liverpool.csv con estos problemas:

  • Columna precio en texto con signos de peso
  • Columna fecha_venta en formato DD/MM/AAAA
  • Algunos registros duplicados
  • Valores nulos en sucursal
import pandas as pd

# Cargar datos
df = pd.read_csv("ventas_liverpool.csv", encoding="latin-1")

# Paso 1: Ver el estado inicial
print(df.info())
print(df.isnull().sum())

# Paso 2: Eliminar duplicados
df = df.drop_duplicates()

# Paso 3: Rellenar nulos en sucursal
df["sucursal"] = df["sucursal"].fillna("Sin asignar")

# Paso 4: Limpiar y convertir precio
df["precio"] = df["precio"].str.replace("$", "", regex=False)
df["precio"] = df["precio"].str.replace(",", "", regex=False)
df["precio"] = pd.to_numeric(df["precio"], errors="coerce")

# Paso 5: Convertir fecha
df["fecha_venta"] = pd.to_datetime(df["fecha_venta"], dayfirst=True, errors="coerce")

# Paso 6: Verificar resultado
print(df.dtypes)
print(df.isnull().sum())

# Calcular ingreso total
df["total"] = df["precio"] * df["cantidad"]
print(df["total"].sum())

Resultado esperado en consola:

precio         float64
cantidad       float64
fecha_venta    datetime64[ns]
sucursal       object

nulos restantes: 0

Ingreso total: $4,872,500

Ese flujo de seis pasos cubre el 90% de los problemas de limpieza en datos reales.


Errores comunes

Error 1: Eliminar nulos sin analizar primero. Si usas .dropna() sin revisar cuántas filas afectas, puedes perder datos importantes. Siempre revisa el porcentaje de nulos antes de decidir.

Error 2: Olvidar reasignar la columna. Muchas operaciones en pandas no modifican el DataFrame original. Debes reasignar:

# INCORRECTO — no guarda el cambio
df["precio"].fillna(0)

# CORRECTO
df["precio"] = df["precio"].fillna(0)

Error 3: Convertir fechas sin especificar el formato. Sin dayfirst=True, pandas puede interpretar 05/04/2024 como 5 de abril en lugar de 4 de mayo. En México eso genera errores silenciosos que arruinan análisis de tendencias.

Error 4: Limpiar texto en el orden equivocado. Siempre elimina caracteres especiales antes de convertir con pd.to_numeric(). Si conviertes primero, obtendrás NaN en todos los valores con signo de peso.


Referencia rápida de funciones de limpieza

Función Uso principal
.isnull().sum() Contar nulos por columna
.dropna() Eliminar filas con nulos
.fillna(valor) Rellenar nulos con un valor
.drop_duplicates() Eliminar filas duplicadas
.duplicated(subset=[...]) Detectar duplicados en columnas específicas
pd.to_numeric() Convertir texto a número
pd.to_datetime() Convertir texto a fecha
.str.replace() Limpiar caracteres no deseados en texto
.dtypes Ver el tipo de dato de cada columna

Lo que debes recordar

  • Siempre revisa .isnull().sum() y .dtypes justo después de cargar cualquier archivo. Esos dos comandos revelan los problemas más comunes.
  • Usa .fillna() cuando perder filas afecte tu análisis; usa .dropna() solo cuando los nulos sean pocos y aleatorios.
  • Limpia el texto con .str.replace() antes de convertir con pd.to_numeric() o pd.to_datetime().
  • En México, las fechas van en formato DD/MM/AAAA: siempre usa dayfirst=True para evitar errores silenciosos.
  • Reasigna siempre el resultado de tus transformaciones: df["columna"] = df["columna"].fillna(...) no es opcional.

Puntos clave

  • Usa `.isnull().sum()` para contar nulos por columna y `.dtypes` para verificar tipos de dato; esos dos comandos son tu punto de partida en cualquier limpieza.
  • Elige `.fillna()` cuando los nulos son muchos y no puedes perder filas; usa `.dropna()` solo cuando los nulos son pocos y su eliminación no distorsiona el análisis.
  • Limpia el texto con `.str.replace()` antes de convertir con `pd.to_numeric()` o `pd.to_datetime()`; el orden importa o obtendrás `NaN` en toda la columna.
  • En México las fechas se escriben `DD/MM/AAAA`; siempre agrega `dayfirst=True` en `pd.to_datetime()` para evitar que abril y mayo se intercambien sin advertencia.
  • Las operaciones de pandas como `.fillna()` no modifican el DataFrame original; siempre reasigna el resultado con `df["columna"] = df["columna"].fillna(...)`.

Comparte esta lección:

¿Cómo limpiar datos sucios con pandas? | Python para Análisis de Datos | Certmundo