PySpark Manejo de Null y NA: Recetas prácticas de limpieza
Updated on
Los nulls rompen métricas, joins y exports cuando se dejan sin controlar. Llamadas silenciosas a dropna también pueden borrar filas valiosas. Los equipos necesitan patrones deliberados para inspeccionar, rellenar, eliminar o comparar nulls de forma segura en PySpark.
Los manejadores de null incorporados de PySpark—fillna, dropna, na.replace, coalesce y las comparaciones null-safe—mantienen los pipelines predecibles y transparentes.
¿Quieres crear rápidamente Data Visualization desde un DataFrame de Python Pandas sin escribir código?
PyGWalker es una librería de Python para Exploratory Data Analysis con Visualization. PyGWalker (opens in a new tab) puede simplificar tu flujo de trabajo de análisis y visualización de datos en Jupyter Notebook, convirtiendo tu pandas dataframe (y polars dataframe) en una interfaz de usuario tipo tableau para exploración visual.
Guía rápida de decisión
| Objetivo | API | Notas |
|---|---|---|
| Rellenar valores por defecto | fillna | Diccionario por columna; respetar tipos |
| Eliminar filas escasas | dropna | Controlar how, thresh, subset |
| Reemplazar sentinelas | na.replace | Cambiar strings o números marcadores |
| Tomar el primer no nulo | coalesce | Combinar columnas por prioridad |
| Igualdad null-safe | <=> o eqNullSafe | Trata los nulls como iguales |
Configuración
from pyspark.sql import SparkSession, functions as F
spark = SparkSession.builder.appName("null-handling").getOrCreate()
df = spark.createDataFrame(
[
(1, "Alice", None, None),
(2, "Bob", "basic", 0),
(3, None, "premium", None),
],
"id INT, name STRING, tier STRING, score INT",
)Inspeccionar patrones de null
null_stats = df.select(
*[
F.sum(F.col(c).isNull().cast("int")).alias(f"{c}_nulls")
for c in df.columns
]
)- Cuenta los nulls por columna antes de decidir si rellenar o eliminar.
Rellenar valores faltantes
filled = df.fillna({"name": "unknown", "tier": "basic", "score": 0})- Proporciona un diccionario para mantener alineados los tipos; evita rellenar numéricos con strings.
- Para fechas/timestamps, usa valores por defecto de dominio (
to_date('1970-01-01')).
Eliminar filas selectivamente
drop_sparse = df.dropna(thresh=3) # keep rows with >=3 non-null values
drop_missing_tier = df.dropna(subset=["tier"])threshprotege frente a eliminar demasiado.- Prefiere subconjuntos de columnas antes que un
dropna()global para preservar filas útiles.
Reemplazar valores sentinela
clean_sent = df.na.replace({"N/A": None, "": None}, subset=["tier", "name"])- Convierte strings marcadores en nulls reales antes de rellenar o eliminar.
Coalesce para tomar el primer no nulo
with_fallback = df.withColumn("primary_tier", F.coalesce("tier", F.lit("basic")))coalescedevuelve el primer valor no nulo en la lista de argumentos.
Comparaciones null-safe
matches = df.where(F.expr("tier <=> 'premium'"))<=>(oeqNullSafe) trata dos nulls como iguales; el operador=normal devuelve null al comparar con null.
Proteger joins posteriores
- Rellena claves de join solo cuando las reglas de negocio lo permitan; de lo contrario filtra explícitamente las claves nulas.
- Para joins fact-to-dimension, decide: eliminar claves nulas antes del join o preservarlas y gestionarlas más adelante.
Pipeline mínimo de limpieza
clean = (
df
.na.replace({"N/A": None, "": None})
.dropna(subset=["name"]) # require a name
.fillna({"tier": "basic", "score": 0})
.withColumn("tier_clean", F.coalesce("tier", F.lit("basic")))
)Esta secuencia estandariza marcadores, mantiene campos requeridos, rellena con valores por defecto de negocio y deja una columna de respaldo clara para reporting.
