PySpark dropDuplicates() and distinct(): deduplicate rows
PySpark `distinct()` removes fully duplicate rows; `dropDuplicates(subset)` removes rows that are duplicates on a chosen subset of columns, keeping the first occurrence. To keep the latest/best row per key, combine a window `row_number()` with a filter instead.
distinct vs dropDuplicates
distinct() dedupes on ALL columns; dropDuplicates(["user_id"]) dedupes on just the listed columns. The row kept is arbitrary unless you order first.
Keep the latest per key
For deterministic dedup (e.g. latest login), use ROW_NUMBER() OVER (PARTITION BY key ORDER BY ts DESC) and keep rn = 1 rather than dropDuplicates.
dropDuplicates vs distinct, and deduplicating on a key
distinct() removes rows that are identical across every column. dropDuplicates() does the same when called with no arguments, but its real value is the subset form: df.dropDuplicates(['customer_id']) keeps one row per customer even when the other columns differ. The catch is that which row survives is not defined — Spark keeps whichever it encounters first, and that can change between runs. Never rely on it when the surviving row matters.
Keeping the latest record per key, deterministically
When you need a specific survivor — usually the most recent version of a record — use a window function instead. Partition by the key, order by the timestamp descending, assign row_number(), then keep rows where the number equals 1. That expresses the intent exactly and gives the same answer every run, which matters for incremental loads and CDC pipelines. If ties are possible, add a tiebreaker column to the ordering so the result stays deterministic.
Example (PySpark)
from pyspark.sql import SparkSession
spark = SparkSession.builder.getOrCreate()
df = spark.createDataFrame([(1, "a"), (1, "a"), (2, "b")], ["id", "val"])
df.distinct().show() # drop fully-identical rows
df.dropDuplicates(["id"]).show() # one row per iddistinct() removes identical rows; dropDuplicates(["id"]) keeps one row per id.
Run this example in the free online PySpark compiler
Frequently asked questions
What is the difference between distinct() and dropDuplicates() in PySpark?
distinct() dedupes across all columns; dropDuplicates(subset) dedupes only on the given columns, keeping one row per unique combination.
How do I keep the latest row per key in PySpark?
Use a window: row_number() over (partitionBy key orderBy timestamp desc) and filter rn = 1 — dropDuplicates keeps an arbitrary row.
Practice challenges
Open the free PySpark compiler · Data Engineering challenges · Data Engineering jobs