2016-12-03 47 views
1

如何在Spark數據框中做鏈功能?在我的代碼中,我想先做大寫,然後進行布爾轉換。但我的代碼沒有工作。謝謝如何在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")))) 

回答

0

首先不要重新發明輪子。對於許多共同的任務,你會發現內置功能:

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")) 
    
相關問題