PySpark按id去重保留非null行问题求助
问题描述
我有如下数据集,包含id和name字段:
| id | name |
|---|---|
| 1 | A |
| 1 | null |
| 2 | A |
| 3 | B |
| 4 | null |
| 4 | B |
| 5 | A |
| 6 | null |
需求是按id去除重复行,优先保留name不为null的行;仅当某id对应的所有行name均为null时,才保留该行。期望输出如下:
| id | name |
|---|---|
| 1 | A |
| 2 | A |
| 3 | B |
| 4 | B |
| 5 | A |
| 6 | null |
我尝试了以下代码:
df .orderBy("name", ascending=False) .dropDuplicates(["id"]) .show(10, False)
该代码虽能去重,但仍会出现name为null的行,需要解决这个问题。
解决方案
问题出在orderBy("name", ascending=False)的排序逻辑上——Spark中null在字符串排序里会被视为最大值,降序排序时null会排在非null值前面,导致dropDuplicates优先保留了null行。以下是两种可行的解决方法:
方法1:自定义优先级排序
通过标记非null值的优先级,确保排序时非null行排在前面:
import org.apache.spark.sql.functions._ df .withColumn("priority", when(col("name").isNotNull, 1).otherwise(0)) .orderBy(col("priority").desc, col("name")) .dropDuplicates("id") .drop("priority") .show(10, false)
方法2:分组聚合选择
按id分组后,直接提取组内第一个非null的name,全为null则保留null:
import org.apache.spark.sql.functions._ df .groupBy("id") .agg(first(when(col("name").isNotNull, col("name")), ignoreNulls=true).alias("name")) .orderBy("id") .show(10, false)
first函数的ignoreNulls=true参数会自动跳过null值,优先选取非null的name;若组内无有效值,则返回null,完全匹配需求。
内容的提问来源于stack exchange,提问作者nbs335
相关产品推荐
相关产品推荐

