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

Spark Scala如何用数组或其他DataFrame的值替换DataFrame null值

实现方案

核心思路:为原表中deptid为null的记录、待填充的deptid值列表分别生成一一对应的连续行号,通过行号做等值关联后完成值填充,完全匹配你「数组长度和null值数量一致、不强制要求emp和deptid对应关系」的前提。

完整Scala Spark代码

import org.apache.spark.sql.expressions.Window
import org.apache.spark.sql.functions._
import spark.implicits._

// 原始员工DataFrame
val emp = Seq(
  (163L, null),
  (843L, null)
).toDF("empID", "deptid")

// 待填充的deptid数组
val range = Array(20L, 21L)

// 1. 给原表中deptid为null的行生成从0开始的连续行号,非null行行号置空
val empWindow = Window.partitionBy(col("deptid").isNull).orderBy("empID")
val empWithRn = emp.withColumn(
  "rn",
  when(col("deptid").isNull, row_number().over(empWindow) - 1)
)

// 2. 将待填充数组转为DataFrame,同样生成从0开始的连续行号
val fillDf = range.toSeq.toDF("fill_deptid")
  .withColumn("rn", row_number().over(Window.orderBy("fill_deptid")) - 1)

// 3. 按行号左关联,用填充值替换null位,删除辅助列
val result = empWithRn
  .join(fillDf, Seq("rn"), "left")
  .withColumn("deptid", coalesce(col("deptid"), col("fill_deptid")))
  .drop("rn", "fill_deptid")

执行result.show()即可得到预期输出:

+-----+------+
|empID|deptid|
+-----+------+
|  163|    20|
|  843|    21|
+-----+------+

说明

  • 窗口的排序字段可任意选择,由于你不要求empID和填充值的绑定关系,只要保证null行的行号连续、和填充列表的行号一一对应即可
  • 方案兼容原表存在非null deptid的场景,已有非null值不会被覆盖,仅填充null位置
  • 之前直接join两个表得到错误结果,是因为没有设置唯一的关联匹配键,无规则连接会产生笛卡尔积或外连接空行,通过行号做关联键可以实现null行和填充值的一对一匹配

内容的提问来源于stack exchange,提问作者amateur-coder

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.03 00:06:32