首页 > 解决方案 > PySpark 中字符串和空值比较的难以理解的结果

问题描述

谁能向我解释字符串和空值之间的比较行为。

数据框:

import pyspark.sql.functions as F

df = spark.createDataFrame([
["text_1,","text_1"],
["text_1,","text_2"],
["text_1,",None]
]).toDF("col1", "col2")


df1 = df.withColumn("equal", F.when(F.col("col1") == F.col("col2"), "equal").otherwise("not equal")
   
+-------+-------+----------+
|col1   |col2   |equal     |
+-------+-------+----------+
|text_1 |text_1 |equal     |
|text_1 |text_2 |not equal |
|text_1 |null   |not equal |  <*
+-------+-------+----------+


df2 = df.withColumn("equal", F.when(F.col("col1") != F.col("col2"), "equal").otherwise("not equal")

+-------+-------+----------+
|col1   |col2   |equal     |
+-------+-------+----------+
|text_1 |text_1 |equal     |
|text_1 |text_2 |not equal |
|text_1 |null   |equal     |   <*
+-------+-------+----------+

比较is equal似乎进展顺利,但is not equal出现了问题。

任何人都可以向我解释这个问题,我如何在不检查或用空字符串.isNotNull填充值的情况下解决这个问题(如果可能)。null

标签: apache-sparkpysparkapache-spark-sqlnull

解决方案


您之所以equal与 null 进行比较,是因为text1 != null给出了 null,该语句将其解释为 false ,因此您从语句中when得到了意外。equalotherwise

您可以使用eqNullSafe,当其中一列为空时,它返回 False 而不是 null。如果要比较不等式,请使用 的否定~eqNullSafe

import pyspark.sql.functions as F

df3 = df.withColumn("equal",
    F.when(~F.col("col1").eqNullSafe(F.col("col2")), "not equal")
     .otherwise("equal")
)

df3.show()
+------+------+---------+
|  col1|  col2|    equal|
+------+------+---------+
|text_1|text_1|    equal|
|text_1|text_2|not equal|
|text_1|  null|not equal|
+------+------+---------+

如果你想用空字符串填充空值,你可以使用coalesce

import pyspark.sql.functions as F

df4 = df.withColumn("equal",
    F.when(F.col("col1") != F.coalesce(F.col("col2"), F.lit("")), "not equal")
     .otherwise("equal")
)

df4.show()
+------+------+---------+
|  col1|  col2|    equal|
+------+------+---------+
|text_1|text_1|    equal|
|text_1|text_2|not equal|
|text_1|  null|not equal|
+------+------+---------+

推荐阅读