首先不要重新發明輪子。對於許多共同的任務,你會發現內置功能:
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")))
功能,用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
。
接下來,您可以使用代替與udf
進行模式匹配的慣用SQL解決方案。比如,你可以使用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,因此並不總是可以進行鏈接。有情況下,當你必須添加單獨udf
結果:
df.withColumn("foo", someUDF("x")).withColumn("bar", someFunc("foo"))