Valores nulos en pandas: detectar y tratar

Los valores nulos en pandas representan datos ausentes. Pueden aparecer como NaN, NaT, None o pd.NA, según el tipo de columna. Detectarlos es sencillo; tratarlos bien exige entender por qué faltan y qué decisión permite el análisis.
Eliminar o rellenar sin contexto puede sesgar medias, inventar actividad o esconder una falla del pipeline. El objetivo no es lograr una tabla “sin huecos”, sino conservar una interpretación válida.
Detectar valores faltantes
import pandas as pd
df.isna().sum()
Para proporciones:
resumen = (
df.isna()
.mean()
.mul(100)
.sort_values(ascending=False)
)
isnull() es alias de isna(); notna() identifica valores presentes. Una cadena vacía, un guion o “N/A” leído como texto puede no contarse como nulo. Normaliza marcadores al importar:
df = pd.read_csv(
"clientes.csv",
na_values=["", "N/A", "sin dato", "-"],
)
Investigar el patrón
Pregunta:
- ¿falta por error de captura?
- ¿la variable no aplica?
- ¿el sensor dejó de reportar?
- ¿el dato está pendiente?
- ¿la ausencia depende de otra variable?
Compara tasas por fuente, fecha o segmento:
df.groupby("origen")["ingreso"].apply(
lambda serie: serie.isna().mean()
)
Si una sucursal tiene 40 % de ausencia y las demás 2 %, el problema probablemente es operativo, no estadístico.
Eliminar con dropna
sin_nulos = df.dropna(subset=["cliente_id", "fecha"])
Puedes exigir un mínimo de valores presentes:
filtrado = df.dropna(thresh=4)
dropna(axis="columns") elimina columnas y debe usarse con cuidado. Antes de borrar filas, mide cuántas se pierden y si ciertos grupos quedan sobrerrepresentados.
Rellenar con fillna
df["descuento"] = df["descuento"].fillna(0)
df["ciudad"] = df["ciudad"].fillna("No informada")
Cero es válido solo si la ausencia significa “ningún descuento”. “No informada” mantiene visible la falta y evita confundirla con una ciudad real.
Para una mediana por segmento:
mediana = df.groupby("categoria")["precio"].transform("median")
df["precio_imputado"] = df["precio"].fillna(mediana)
Conserva un indicador:
df["precio_era_nulo"] = df["precio"].isna()
Así el modelo o auditor puede distinguir el valor observado del imputado.
Forward fill e interpolación
serie = serie.ffill(limit=2)
serie = serie.interpolate(method="linear", limit=2)
ffill propaga el último valor; interpolar estima entre puntos. Solo tienen sentido en datos ordenados donde la continuidad sea defendible. Nunca propagues entre clientes o sensores distintos:
df["estado"] = (
df.sort_values(["cliente_id", "fecha"])
.groupby("cliente_id")["estado"]
.ffill()
)
Para ordenar y convertir tiempos correctamente, revisa fechas en pandas.
Tipos anulables
pandas ofrece tipos como Int64, boolean y string que admiten pd.NA sin convertir enteros a float:
df["unidades"] = df["unidades"].astype("Int64")
df["activo"] = df["activo"].astype("boolean")
Verifica las operaciones: las comparaciones con ausencias pueden propagar un resultado desconocido.
Imputación y machine learning
Calcula parámetros de imputación únicamente con el conjunto de entrenamiento. Si usas la mediana de todo el dataset antes de la validación cruzada, filtras información del conjunto de evaluación.
Una Pipeline permite ajustar el imputador dentro de cada pliegue. Compara además el modelo contra una estrategia simple y evalúa por subgrupo.
No sobrescribir demasiado pronto
Durante el análisis conserva:
- columna original;
- columna tratada;
- indicador de imputación;
- método y parámetros;
- fecha y versión del proceso.
Esto mejora trazabilidad y permite cambiar la estrategia sin perder el dato bruto.
Errores frecuentes
- Reemplazar todo nulo por cero.
- Eliminar filas sin medir el sesgo.
- Imputar antes de dividir entrenamiento y prueba.
- Tratar cadena vacía como valor válido.
- Aplicar forward fill entre entidades.
- Promediar categorías o códigos.
- Sobrescribir la columna original sin registro.
- Reportar métricas sin tasa de completitud.
La limpieza de datos debe incluir reglas preventivas en origen. Imputar es una decisión analítica, no la reparación definitiva de una captura defectuosa.
Preguntas frecuentes
¿Cómo cuento nulos en pandas?
Usa df.isna().sum() para cantidades o df.isna().mean() para proporciones por columna.
¿NaN y None son iguales?
No internamente, aunque pandas los reconoce como ausencias en muchos contextos. El tipo de columna determina la representación.
¿Cuándo debo usar dropna?
Cuando las filas faltantes no son necesarias y su eliminación no introduce un sesgo inaceptable. Mide siempre el impacto.
¿Es correcto rellenar nulos con cero?
Solo si cero representa fielmente la ausencia. En otros casos inventa un valor y altera estadísticas.
¿Qué hace ffill?
Propaga el último valor observado. Debe aplicarse sobre datos ordenados y dentro de cada entidad.
¿Cómo evito fuga de datos al imputar?
Ajusta la estrategia solo con entrenamiento, idealmente dentro de una Pipeline y de cada pliegue de validación.

Deja una respuesta