Spark UDF中键入不匹配

时间:2018-02-05 15:13:49

标签: scala apache-spark apache-spark-sql user-defined-functions

我创建了以下UDF来仅获取十进制值的第一部分。

def udf_cleansing(col1 : Double) = udf((col1 : Double) => {
val col2 : String = f"$col1%.5f"
if(col2.trim == "" || col2 == null ) 0.toString else col2.substring(0,col2.indexOf("."))}
)

但是,使用

之类的命令调用此函数时
df_aud.select(udf_cleansing(df_aud("HASH_TTL")))

我得到了以下错误: -

  

< console>:42:错误:类型不匹配;

     

发现:org.apache.spark.sql.Column

     

必需:Double

     

df_aud.select(udf_cleansing(df_aud(" HASH_TTL")))

我尝试了命令

df_aud.withColumn("newc",udf_cleansing(df_aud("HASH_TTL").cast("double")))

仍有同样的错误。

2 个答案:

答案 0 :(得分:2)

原因是Scala将df_aud("HASH_TTL")视为udf_cleansing函数的参数,而不是将此函数返回给UDF。

相反,你应该写:

def udf_cleansing = udf(
    (col1 : Double) => {
        val col2 : String = f"$col1%.5f"
        if(col2.trim == "" || col2 == null ) 0.toString else col2.substring(0,col2.indexOf("."))
    }
)

现在udf_cleansing返回一个UDF。 UDF1用作Column类型的参数,该列的值提供给包装的内部函数。

然后使用正是您尝试使用此功能的方式。

答案 1 :(得分:0)

我建议您尽可能使用spark functions。如果任何内置函数无法满足您的需求,那么只有我建议您使用udf函数作为udf函数才需要将数据序列化反序列化以执行您设计的操作。

您的udf功能可以使用format_stringsubstring_index 内置功能执行,如下所示

import org.apache.spark.sql.functions._
df_aud.select(substring_index(format_string("%.5f", df_aud("HASH_TTL")), ".", 1))