如何在Spark数据帧中执行链函数?在我的代码中,我想先做大写,然后再进行布尔转换。但我的代码无法正常工作。谢谢
import org.apache.spark.sql.functions.udf
val trimStr: String => String = _.trim
val trimUDF = udf(trimStr)
import org.apache.spark.sql.functions.udf
val upperCaseStr: String => String = _.toUpperCase
val upperCaseUDF = udf(upperCaseStr)
import org.apache.spark.sql.functions.udf
def booleanValueSubstitution = udf[String, String] {
case "" => "N"
case null => "N"
case "TRUE" => "Y"
}
var df= df1.withColumn("xx", booleanValueSubstitution(upperCaseUDF(df1("yy"))) )
首先,不要重新发明轮子。对于许多常见任务,您会发现内置函数:
import org.apache.spark.sql.functions.{trim, upper}
除其他好处外,这是null
安全的:
val df = Seq(None, Some(""), Some("true"), Some(" TRUE "), Some("foo")).toDF("x")
df.select(upper(trim($"x")))
+--------------+
|upper(trim(x))|
+--------------+
| null|
| |
| TRUE|
| TRUE|
| foo|
+--------------+
您定义的函数(除外)booleanValueSubstitution
不是。每次遇到代码时NULL
,都会由于NPE而失败,因此,如果您决定重新发明轮子,则应该始终予以解决。
您可以像使用一样进行模式匹配,也booleanValueSubstitution
可以使用Try
:
import scala.util.Try
val upperCaseUDF = udf((s: String) => Try(s.toUpperCase).toOption)
val trimUDF = udf((s: String) => Try(s.trim).toOption)
如果决定使用模式匹配,请确保条件详尽无遗:
val booleanValueSubstitution = udf[String, String] {
case "" => "N"
case null => "N"
case "TRUE" => "Y"
case _ => "N"
}
或更简单:
val booleanValueSubstitution = udf[String, String] {
case "TRUE" => "Y"
case _ => "N"
}
否则你会得到的scala.MatchError
。
接下来,存在一些惯用的SQL解决方案,您可以使用它们代替进行模式匹配udf
。例如,您可以使用CASE WHEN
:
import org.apache.spark.sql.functions.{when, coalesce, lit}
df.select(
when($"x".isNull, "N").when($"x" === "", "N").when($"x" === "TRUE", "Y")
)
或者:
df.select(coalesce(when($"x" === "TRUE", "Y").otherwise("N"), lit("N")))
最后,如果您认为布尔值,最好使用布尔值:
when($"x".isNull, false).when($"x" === "", false).otherwise(true)
一般来说:
不允许在每个位置上都使用UDF,因此不一定总是可以链接。在某些情况下,您必须分别添加udf
结果:
df.withColumn("foo", someUDF("x")).withColumn("bar", someFunc("foo"))
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句