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

Spark Full Join出现含Null键的重复行是否属于正常行为?

PySpark Full Join 结果疑问解答

问题描述

执行以下PySpark代码后,结果中出现两行键为[4, null]的记录,请问该Full Join行为是否正常?

测试代码

from datetime import *
from pyspark.sql.functions import *
from pyspark.sql.types import *

columns = [ 'id1', 'id2', 'val' ]
ids = [ 'id1', 'id2' ]

vals1 = [
        (1, 'a', 1),
        (2, 'b', 4),
        (4, None, 1),
      ]
df1 = spark.createDataFrame(data=vals1, schema=columns)

vals2 = [
        (1, 'a', 5),
        (3, 'c', 2),
        (4, None, 2),
      ]
df2 = spark.createDataFrame(data=vals2, schema=columns)

df1 = df1.withColumnRenamed('val', 'val1')
df2 = df2.withColumnRenamed('val', 'val2')

res_df = df1.join(df2, ids, 'full')

res_df.sort(ids).show()

执行结果

+---+----+----+----+
|id1| id2|val1|val2|
+---+----+----+----+
|  1|   a|   1|   5|
|  2|   b|   4|null|
|  3|   c|null|   2|
|  4|null|   1|null|
|  4|null|null|   2|
+---+----+----+----+

解答

这是正常行为,核心原因是Spark的Join逻辑遵循SQL标准:NULL值不被视为相等的匹配键。

具体逻辑:

  • df1中的(4, None, 1)和df2中的(4, None, 2),虽然id1都是4,但id2的值为NULL
  • 在Join匹配时,Spark不会将两个NULL值判定为相等,因此这两条记录无法匹配
  • Full Join会保留左右表中所有未匹配的记录,所以最终结果里会出现这两条分别来自df1和df2的记录

如果需要让NULL值的键也能匹配,可以先对连接字段的NULL值做替换处理,比如用coalesce函数将NULL替换为特定非空值后再执行Join,示例如下:

# 对id2字段的NULL值替换为占位符
df1_processed = df1.withColumn("id2", coalesce(col("id2"), lit("__NULL__")))
df2_processed = df2.withColumn("id2", coalesce(col("id2"), lit("__NULL__")))

res_df = df1_processed.join(df2_processed, ids, 'full')
# 可选:将占位符还原为NULL
res_df = res_df.withColumn("id2", when(col("id2") == "__NULL__", lit(None)).otherwise(col("id2")))
res_df.sort(ids).show()

内容的提问来源于stack exchange,提问作者user626528

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.18 21:15:41