Scala:可变参数 UDF

Posted

技术标签:

【中文标题】Scala:可变参数 UDF【英文标题】:Scala: variadic UDF 【发布时间】:2016-10-28 14:19:22 【问题描述】:

我有一个包含很多列的 DataFrame。 我也有功能

def getFeatureVector(features:Array[String]) : Vector

这相当复杂,但需要一些字符串并返回 spark MLlib 向量。

现在,我想查看 DF 中的一些列(我事先不知道是哪一列),将它们传递给 getFeatureVector,然后添加一个包含结果向量的新列。

我可以访问我想要使用的列的数组,并且我编写了一个将其转换为字符串的函数,并创建了一个数组列:

val colNamesToEncode = Array("col1", "col2", "col3", "col4")
def getColsToEncode:Column = 
    val cols = colNamesToEncode.map(x => col(x).cast("string"))
    array(cols:_*)

最后,我尝试制作一个 udf 并将其应用于 DF:

val encoderUDF = udf(getFeatureVector _)
val cols = getColsToEncode()
data.withColumn(featuresColName,encoderUDF(cols))

但是当我运行它时,我得到 java.lang.RuntimeException: Unsupported literal type class scala.runtime.BoxedUnit ()

如何向 DF 申请函数?

PS:我在编写代码时使用此答案 (Spark UDF with varargs) 作为指南。

【问题讨论】:

【参考方案1】:

只需从下面的行中删除(),即可解决错误。

来自val cols = getColsToEncode()

val cols = getColsToEncode

【讨论】:

【参考方案2】:

可以直接将函数传入udf函数。

val colNamesToEncode = Array("col1", "col2", "col3", "col4")
def getColsToEncode:Column = 
val cols = colNamesToEncode.map(x => col(x).cast("string"))
array(cols:_*)


val encoderUDF = udf(getFeatureVector _)
data.withColumn(featuresColName,encoderUDF(getColsToEncode))

【讨论】:

以上是关于Scala:可变参数 UDF的主要内容,如果未能解决你的问题,请参考以下文章

Spark Sql udf,参数数量可变

UDF:处理范围和可变数量的参数

创建具有可变数量参数的 CLR UDF

pyspark udf 的可变参数数量

Scala可变参数列表,命名参数和参数缺省

Scala 可变长参数