![](/img/trans.png)
[英]Make spark-sql UDF available in Scala spark data frame DSL API
[英]Spark scala data frame udf returning rows
假設我有一個 dataframe,它包含一個列(稱為 colA),它是一行的序列。 我想 append 一個新字段到 colA 的每條記錄。 (而且新的filed是和以前的記錄相關聯的,所以我得寫一個udf。)這個udf應該怎么寫?
我嘗試編寫一個 udf,它將 colA 作為輸入,以及 output Seq[Row],其中每條記錄都包含新字段。 但問題是 udf 無法返回 Seq[Row]/ 異常是'Schema for type org.apache.spark.sql.Row is not supported'。 我應該怎么辦?
我寫的 udf: val convert = udf[Seq[Row], Seq[Row]](blablabla...)
異常是 java.lang.UnsupportedOperationException: Schema for type org.apache.spark.sql.Row is不支持
從spark 2.0開始,您可以創建返回Row
/ Seq[Row]
UDF,但是您必須提供返回類型的模式,例如,如果您使用雙精度數組:
val schema = ArrayType(DoubleType)
val myUDF = udf((s: Seq[Row]) => {
s // just pass data without modification
}, schema)
但我真的無法想象這有用的地方,我寧願從UDF中返回元組或案例類(或其Seq)。
編輯:如果您的行包含超過22個字段(元組/案例類的字段限制)可能很有用
這是一個老問題,我只是想根據新版本的Spark更新一下。
從 Spark 3.0.0 開始,@Raphael Roth 提到的方法已被棄用。 因此,您可能會得到一個AnalysisException
。 原因是使用此方法的輸入閉包沒有類型檢查,當涉及到null
值時,行為可能與我們在 SQL 中預期的不同。
如果您真的知道自己在做什么,則需要將spark.sql.legacy.allowUntypedScalaUDF
配置設置為true
。
另一種解決方案是使用case class
而不是模式。 例如,
case class Foo(field1: String, field2: String)
val convertFunction: Seq[Row] => Seq[Foo] = input => {
input.map {
x => // do something with x and convert to Foo
}
}
val myUdf = udf(convertFunction)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.