我有一些UDF,我希望将它作为函数参数与数据帧一起传递。
执行此操作的一种方法可能是在函数内创建UDF,但这会创建并销毁UDF的多个实例而不重用它,这可能不是解决此问题的最佳方法。
这是一段代码示例 -
val lkpUDF = udf{(i: Int) => if (i > 0) 1 else 0}
val df = inputDF1
.withColumn("new_col", lkpUDF(col("c1")))
val df2 = inputDF2.
.withColumn("new_col", lkpUDF(col("c1")))
我没有做上述事情,而是希望做到这样的事情 -
val lkpUDF = udf{(i: Int) => if (i > 0) 1 else 0}
def appendCols(df: DataFrame, lkpUDF: ?): DataFrame = {
df
.withColumn("new_col", lkpUDF(col("c1")))
}
val df = appendCols(inputDF, lkpUDF)
上面的UDF非常简单,但在我的情况下,它可以返回基本类型或用户定义的case类类型。任何想法/指针将不胜感激。感谢。
答案 0 :(得分:3)
具有相应签名的功能需要:
import org.apache.spark.sql.UserDefinedFunction
def appendCols(df: DataFrame, func: UserDefinedFunction): DataFrame = {
df.withColumn("new_col", func(col("col1")))
}
scala REPL非常有助于返回初始化值的类型。
scala> val lkpUDF = udf{(i: Int) => if (i > 0) 1 else 0}
lkpUDF: org.apache.spark.sql.UserDefinedFunction = UserDefinedFunction(<function1>,IntegerType,List(IntegerType))
此外,如果传递给udf
包装器的函数的签名包含Any
返回类型(如果函数可以返回基元或用户定义的情况,则会出现这种情况)案例类),UDF将无法编译,例如:
java.lang.UnsupportedOperationException: Schema for type Any is not supported