Cómo eliminar filas duplicadas con PySpark en Databricks
Los datos duplicados aparecen por reprocesos, cargas repetidas o joins mal diseñados, y enseguida inflan los recuentos, distorsionan las métricas y rompen los informes. Eliminar filas duplicadas con PySpark en Databricks es una de las tareas de limpieza más habituales del día a día, y es sencillo cuando conoces las funciones adecuadas. Esta guía muestra, paso a paso, cómo detectar y eliminar duplicados, ya sea en todas las columnas o solo en las que definen un registro único. Al final, guardarás el resultado en una tabla Delta lista para reutilizar.
Requisitos previos
- Un workspace de Databricks con un cluster (o SQL warehouse) activo.
- Un notebook de Python conectado al cluster.
- Conocimientos básicos de Python y del concepto de DataFrame.
- La variable
sparkya está disponible en cualquier notebook de Databricks.
Paso 1: Crear un DataFrame de ejemplo con duplicados
Para seguir el ejemplo, empezamos creando un DataFrame pequeño. Fíjate en que la fila de id=2 está totalmente repetida y en que id=3 aparece dos veces con ciudades distintas, es decir, un duplicado solo en la columna clave. Estos dos casos requieren estrategias diferentes, como verás.
from pyspark.sql import Row
dados = [
Row(id=1, cliente="Ana", cidade="Porto", atualizado="2026-07-10"),
Row(id=2, cliente="Bruno", cidade="Lisboa", atualizado="2026-07-11"),
Row(id=2, cliente="Bruno", cidade="Lisboa", atualizado="2026-07-11"),
Row(id=3, cliente="Rita", cidade="Braga", atualizado="2026-07-12"),
Row(id=3, cliente="Rita", cidade="Faro", atualizado="2026-07-15"),
]
df = spark.createDataFrame(dados)
df.show()
Paso 2: Contar los duplicados antes de borrar
Antes de eliminar nada, conviene saber cuántos duplicados existen: así confirmas el impacto de la limpieza y detectas sorpresas. Agrupar por todas las columnas y filtrar los grupos con más de una fila revela las repeticiones exactas. Guarda este número: al final lo compararás con el recuento final para confirmar cuántas filas se eliminaron.
print("Total de linhas:", df.count())
duplicados = (df.groupBy(df.columns)
.count()
.filter("count > 1"))
duplicados.show()
Paso 3: Eliminar filas totalmente duplicadas
Cuando dos filas son iguales en todas las columnas, el método dropDuplicates() sin argumentos resuelve el problema y conserva solo una copia de cada fila. El método distinct() hace exactamente lo mismo y es solo una forma más corta de escribirlo. Ambos provocan un shuffle, así que aplícalos después de haber descartado las columnas innecesarias.
sem_duplicados = df.dropDuplicates()
print("Depois de dropDuplicates():", sem_duplicados.count())
# Equivalente:
sem_duplicados = df.distinct()
Paso 4: Eliminar duplicados por columna clave
A menudo una fila se considera duplicada según una clave de negocio (por ejemplo, el id), aunque las demás columnas varíen. Para ese caso, indica las columnas a considerar y Spark elimina duplicados solo por ellas.
por_chave = df.dropDuplicates(["id"])
por_chave.show()
Atención: al usar un subconjunto de columnas, Spark conserva una fila cualquiera de cada grupo; no garantiza cuál de las filas se queda. Si eso importa, usa el paso siguiente.
Paso 5: Conservar el registro más reciente
Cuando quieres controlar qué fila sobrevive — por ejemplo, quedarte con la versión más reciente de cada id — usa una ventana (Window) con row_number(). La idea es numerar las filas dentro de cada grupo, ordenadas por fecha descendente, y conservar solo la que recibe el número 1.
from pyspark.sql.window import Window
from pyspark.sql.functions import row_number, col
janela = Window.partitionBy("id").orderBy(col("atualizado").desc())
mais_recente = (df.withColumn("rn", row_number().over(janela))
.filter(col("rn") == 1)
.drop("rn"))
mais_recente.show()
Con este enfoque, id=3 se queda con la ciudad "Faro", por ser la actualización del 2026-07-15, y descartas la versión antigua de forma controlada.
Paso 6: Guardar el resultado en una tabla Delta
Para reutilizar los datos ya limpios, guarda el DataFrame en una tabla Delta gestionada. Ajusta el nombre del catálogo y del esquema a tu entorno.
(mais_recente.write
.format("delta")
.mode("overwrite")
.saveAsTable("vendas.clientes_limpos"))
Verificar el resultado
Compara el recuento antes y después y confirma que ya no existe ninguna clave repetida. Si la última consulta no devuelve filas, la limpieza funcionó como esperabas: pasaste de 5 filas a 3 registros únicos por id.
print("Linhas originais:", df.count())
print("Linhas finais:", mais_recente.count())
(mais_recente.groupBy("id")
.count()
.filter("count > 1")
.show())
Conclusión
En unos pocos pasos pasaste de datos repetidos a un conjunto limpio y fiable: dropDuplicates() para filas idénticas, un subconjunto de columnas para claves de negocio y una Window cuando necesitas elegir exactamente qué registro conservar. A partir de aquí, puedes programar este notebook como un Job para que se ejecute automáticamente, o combinar la lógica con MERGE INTO para eliminar duplicados de forma incremental a medida que llegan nuevos datos. ¿Cuál será la columna clave que mejor identifica un registro único en tus propios datos?