PySpark DataFrame比对差异时!=过滤漏空值问题求解
原因说明
- 在Spark SQL的三值逻辑规则中,任何涉及
NULL的比较运算(==、!=、>、<等)返回结果都为NULL,而where子句仅会保留条件计算结果为True的行,结果为False或NULL的行都会被过滤。 - 你的代码中
df1['name'] != df2['name']这个条件,在id=3(df2.name为NULL)、id=6(df1.name为NULL)的行中,运算结果都为NULL,因此这两行被过滤,仅返回两边name都非空且不等的id=2的行,属于符合规则的正常行为,DataFrame创建过程没有隐藏逻辑。
修复方案
使用空值安全的等值判断方法eqNullSafe取反,即可覆盖包含NULL的不等场景:
import pyspark.sql.functions as F differences = df1.join(df2, df1['id'] == df2['id'], how='full') \ .select(F.coalesce(df1['id'], df2['id']).alias('id'), df1['name'], df2['name']) \ .where(~df1['name'].eqNullSafe(df2['name']))
eqNullSafe方法的判断规则为:两边值相等(含两边都为NULL)时返回True,否则返回False,取反后正好匹配你需要的「两个name不一致(含单侧为NULL)」的过滤需求,运行后会返回你预期的三行结果。
也可以显式写全所有匹配条件,逻辑等价:
.where( (df1['name'] != df2['name']) | df1['name'].isNull() | df2['name'].isNull() )
内容的提问来源于stack exchange,提问作者Ben
相关产品推荐
相关产品推荐

