Spark中when().otherwise多条件使用异常:生成immediate布尔列不符预期
问题分析与解决方案
你的代码逻辑本身没问题,但出现不符合预期的结果,大概率是目标列中存在看起来像null但实际不是SQL标准null的值(比如空字符串""、空数组、空结构体等),导致isNull判断返回false,进而触发otherwise(true)。
解决方案1:覆盖空值场景的修正写法
把原判断中的isNull替换为同时检查空值和空内容,针对字符串列补充空字符串判断,数值列保留isNull即可:
val evaluation = evaluation_raw .withColumn("immediate", when( (col("intended_outcome_review").isNull || col("intended_outcome_review") === "") && (col("outcome").isNull || trim(col("outcome")) === "") && col("impact").isNull && col("impact_self").isNull && (col("next_step").isNull || trim(col("next_step")) === ""), lit(false)) .otherwise(lit(true))) .select( col("id"), col("intended_outcome_review"), col("outcome"), col("impact"), col("impact_self"), col("next_step"), col("immediate"))
解决方案2:更简洁的通用写法
利用Spark的array_exists函数,直接判断目标列中是否存在非空值,逻辑更直观:
val targetCols = Seq("intended_outcome_review", "outcome", "impact", "impact_self", "next_step") val evaluation = evaluation_raw .withColumn("immediate", array_exists(array(targetCols.map(col): _*), x => x.isNotNull && trim(x) =!= "")) .select( col("id"), col("intended_outcome_review"), col("outcome"), col("impact"), col("impact_self"), col("next_step"), col("immediate"))
如果是纯数值列,可去掉trim(x) =!= "",仅保留x.isNotNull。
验证步骤
先排查id=1569的行,执行以下代码查看列的实际值类型,确认是否存在非null的空内容:
evaluation_raw.filter(col("id") === 1569) .select(targetCols.map(c => col(c).cast(StringType).alias(s"${c}_str")): _*) .show(false)
内容的提问来源于stack exchange,提问作者jackdotdi
相关产品推荐
相关产品推荐

