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
相关产品推荐
相关产品推荐

