![](/img/trans.png)
[英]How to register Scala UDF in spark-SQL, not Spark-Scala?
[英]Creting UDF function with NonPrimitive Data Type and using in Spark-sql Query: Scala
I am creating one function in scala which i want to use in my spark-sql query.my query is working fine in hive or if i am giving the same query in spark sql but the same query i'm using at multiple places so i想將它創建為可重用的函數/方法,所以只要它需要我就可以調用它。 我在我的 scala class 中創建了下面的 function。
def date_part(date_column:Column) = {
val m1: Column = month(to_date(from_unixtime(unix_timestamp(date_column, "dd-MM-yyyy")))) //give value as 01,02...etc
m1 match {
case 01 => concat(concat(year(to_date(from_unixtime(unix_timestamp(date_column, "dd-MM- yyyy"))))-1,'-'),substr(year(to_date(from_unixtime(unix_timestamp(date_column, "dd-MM-yyyy")))),3,4))
//etc..
case _ => "some other logic"
}
}
但它顯示多個錯誤。
◾十進制 integer 文字可能沒有前導零。 (八進制語法已過時。)
◾類型不匹配; 找到:需要 Int(0):org.apache.spark.sql.Column。
類型不匹配; 找到:需要字符('-'):org.apache.spark.sql.Column。
未找到:值 substr。
另外,如果我要創建任何簡單的 function 並且類型為列,我將無法注冊它,因為我在列格式中無法獲得錯誤。對於所有原始數據類型(字符串、長整數、整數)它的工作很好。但在我的情況下,類型是列,所以我無法做到這一點。有人可以指導我該怎么做。截至目前,我在堆棧溢出上發現我需要將這個 function 與 df 一起使用,然后需要將此df轉換為臨時表。有人可以指導我任何其他替代方式,因此無需對現有代碼進行太多更改,我就可以使用此功能。
首先,Spark 需要讀取一個存儲數據的文件,我猜這個文件是 CSV 但你可以使用 csv 的方法 json。
然后,您可以添加具有計算值的新列,如下所示:
import org.apache.spark.sql.functions._
val df = spark.read
.option("header", "true")
.option("inferSchema", "true")
.csv("/path/mydata.csv")
def transformDate( dateColumn: String, df: DataFrame) : DataFrame = {
df.withColumn("calculatedCol", month(to_date(from_unixtime(unix_timestamp(col(dateColumn), "dd-MM-yyyy")))))
df.withColumn("newColumnWithDate", when(col("calculatedCol") === "01", concat(concat(year(to_date(from_unixtime(unix_timestamp(col("calculatedCol"), "dd-MM- yyyy"))))-1, lit('-')),substring(year(to_date(from_unixtime(unix_timestamp(col("calculatedCol")), "dd-MM-yyyy"))),4,2))
.when(col("calculatedCol") === "02","some other logic")
.otherwise("nothing match")))
}
// calling your function for the Dataframe you want transform date column:
transformDate("date_column", df)
請注意,某些函數需要列作為參數,而不是字符串值,因此請使用 lit() 指定該值。
不需要 UDF(並且在性能方面不推薦),但您可以通過以下方式使用它:
val upper: String => String = _.toUpperCase
import org.apache.spark.sql.functions.udf
val upperUDF = udf(upper)
df.withColumn("upper", upperUDF('text)).show
其中“上” function 將是您必須包含轉換日期列的邏輯的方法。
試試下面的代碼。
scala> import org.joda.time.format._
import org.joda.time.format._
scala> spark.udf.register("datePart",(date:String) => DateTimeFormat.forPattern("MM-dd-yyyy").parseDateTime(date).toString(DateTimeFormat.forPattern("MMyyyy")))
res102: org.apache.spark.sql.expressions.UserDefinedFunction = UserDefinedFunction(<function1>,StringType,Some(List(StringType)))
scala> spark.sql("""select datePart("03-01-2019") as datepart""").show
+--------+
|datepart|
+--------+
| 032019|
+--------+
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.