You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PySpark按id去重保留非null行问题求助

问题描述

我有如下数据集,包含id和name字段:

idname
1A
1null
2A
3B
4null
4B
5A
6null

需求是按id去除重复行,优先保留name不为null的行;仅当某id对应的所有行name均为null时,才保留该行。期望输出如下:

idname
1A
2A
3B
4B
5A
6null

我尝试了以下代码:

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.24 22:51:06