Adi*_*l B 2 python evaluation boolean pyspark short-circuit-evaluation
我想在我的数据框中创建一个新的布尔列,该列从同一数据框中其他列上的两个条件语句的评估中得出其值:
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"))
Run Code Online (Sandbox Code Playgroud)
除非color_one或color_two连续为 NULL,否则这工作正常。在此类情况下,该行is_red也设置NULL为而不是trueor false:
+-------+----------+------------+-------+
|id |color_one |color_two |is_red |
+-------+----------+------------+-------+
| 1| blue| red| true|
| 2| red| NULL| NULL|
+-------+----------+------------+-------+
Run Code Online (Sandbox Code Playgroud)
这意味着如果第一个条件恰好为真(如上面示例的第 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"))))
)
Run Code Online (Sandbox Code Playgroud)
我不认为 Spark 支持对条件进行短路评估,如此处所述https://docs.databricks.com/spark/latest/spark-sql/udf-python.html#:~:text=Spark%20SQL% 20(包括,短路%E2%80%9D%20语义。 :
\n\n\nSpark SQL(包括 SQL 以及 DataFrame 和 Dataset API)不保证子表达式的计算顺序。特别是,运算符或函数的输入不一定从左到右或以任何其他固定顺序进行评估。例如,逻辑 AND 和 OR 表达式不具有从左到右的 \xe2\x80\x9cshort-Circuiting\xe2\x80\x9d 语义。
\n
另一种替代方法是创建一个由column_one和column_two组成的数组,然后使用 SQL评估该数组是否包含“red”EXISTS
data = data.withColumn(\'is_red\', F.expr("EXISTS(array(color_one, color_two), x -> x = \'red\')"))\ndata.show()\n+---+---------+---------+------+\n| id|color_one|color_two|is_red|\n+---+---------+---------+------+\n| 1| blue| red| true|\n| 2| red| null| true|\n| 3| null| green| false|\n| 4| yellow| null| false|\n| 5| null| red| true|\n| 6| null| null| false|\n+---+---------+---------+------+\nRun Code Online (Sandbox Code Playgroud)\n
| 归档时间: |
|
| 查看次数: |
1105 次 |
| 最近记录: |