Scala Spark - udf列不受支持

Alg*_*g_D 1 scala user-defined-functions apache-spark apache-spark-sql

我试图使用一个udf相当于:

df.select(when(col("abc").isNotNull and col("abc") =!= "" and col("age") <= 18, 1).otherwise(0).alias("something"))

我声明了udf这样的意思:

//return Int 0 or 1 if conditions are true 
val myudf_x = udf((col_name: String, col_value: String, num: Int) => {
  when(col_name.isNotNull and col_name =!= "" and col_value < num, 1).otherwise(0)

})
Run Code Online (Sandbox Code Playgroud)

用法:

  df.select(
  "col_abc",
  myudf(col("col_abc"), col("age"), 18).alias("something")
)
Run Code Online (Sandbox Code Playgroud)

但是我收到一个错误:

不支持类型为org.apache.spark.sql.Column的模式

我也尝试过String类型而不是column类型的udf

有什么问题?

谢谢

hi-*_*zir 6

一个简单的区别:

  • 表达式对SQL类型(Columns)进行操作.
  • udfs 对外部(Scala)类型进行操作.

如果你想要一个使用表达式DSL的函数:

import org.apache.spark.sql.Column

// You can use function:
// def f(col_name: Column, col_value: Column, num: Column) = ???
// I used closure syntax to highlight difference in types
val f: (Column, Column, Column) => Column = 
  (col_name: Column, col_value: Column, num: Column) =>  when(
    col_name.isNotNull and col_name =!= "unknown" and col_value < num, 
    1
  ).otherwise(0)
Run Code Online (Sandbox Code Playgroud)

除此以外:

val g: UserDefinedFunction = udf(
  (col_name: String, col_value: String, num: Int) => {
    if (col_name != null && col_name != "unknown" && col_value < num) 1 else 0
  }
)
Run Code Online (Sandbox Code Playgroud)

但是在当前形式下,udf将不会进行类型检查(col_value是a Stringnumis Int- 它们无法进行比较<).

也许你想col_value.cast("int") < num/ col_value.toInt < num