我想在我的数据框中创建一个新的布尔列,它的值来自对同一数据框中其他列的两个条件语句的评估:
columns = ["id", "color_one", "color_two"]
data = spark.createDataFrame([(1, "blue", "red"), (2, "red", None)]).toDF(*columns)
data = data.withColumn('is_red', data.color_one.contains("red") | data.color_two.contains("red"))
除非连续为 NULLcolor_one
或NULL,否则这可以正常工作。color_two
在这种情况下,is_red
也设置NULL
为该行而不是true
or false
:
+-------+----------+------------+-------+
|id |color_one |color_two |is_red |
+-------+----------+------------+-------+
| 1| blue| red| true|
| 2| red| NULL| NULL|
+-------+----------+------------+-------+
这意味着如果第一个条件恰好为真(如上面示例的第 2 行),PySpark 正在评估条件语句的所有子句,而不是提前退出(通过短路评估)。
PySpark 是否支持条件语句的短路评估?
同时,这是我想出的一种解决方法,可以对每一列进行空值检查:
from pyspark.sql import functions as F
color_one_is_null = data.color_one.isNull()
color_two_is_null = data.color_two.isNull()
data = data.withColumn('is_red', F.when(color_two_is_null, data.color_one.contains("red"))
.otherwise(F.when(color_one_is_null, data.color_two.contains("red"))
.otherwise(F.when(color_one_is_null & color_two_is_null, F.lit(False))
.otherwise(data.color_one.contains("red") | data.color_two.contains("red"))))
)