我刚开始学习Spark。我试图为我的数据框定义一个UDF。这是一个非常简单的函数:列在数据框中是Long类型。
def category: (Int => Int) ={ a=>
if(a<7){
return a
}
else{
if(a>=7 && a<14){
return 8
}
else{
if(a>=14 && a<28){
return 9
}
else{
return 10
}
}
}
}
import org.apache.spark.sql.functions.udf
val myudf = udf(category)
val df_1 = df.withColumn("ncol", myudf($col))
它总是报告错误:
:78: error: type mismatch; found : Int required: Int => Int return a ^ :82: error: type mismatch; found : Int(8) required: Int => Int return 8 ^ :86: error: type mismatch; found : Int(9) required: Int => Int return 9 ^ :89: error: type mismatch; found : Int(10) required: Int => Int return 10 ^
答案 0 :(得分:2)
摆脱你的退货声明。大多数scala代码中都不需要return
,因为最后一个表达式是自动返回的(这也适用于if语句,整个if是一个返回值的语句)。不建议您在不需要时使用return
,因为它可能会导致您遇到的一些意外行为。
让我们简化您的代码
def category: (Int => Int) ={ a=>
return a
}
这将无法编译。 category
是一个不带参数并返回函数Int => Int
的方法。到现在为止还挺好。但现在return a
会导致该方法返回a
的值,即Int
。因为我们想要Int => Int
并且我们返回Int
,这会中断。要解决此问题,只需删除返回。
def category: (Int => Int) = { a=>
a
}
现在代码有效,因为我们方法中的最后一个(也是唯一一个)表达式是函数a => a
,它就像我们想要的Int => Int
一样。这里的函数有点无聊,它只是返回输入而没有变化。
让我们试试你的功能
def category: (Int => Int) ={ a=>
if(a<7){
a
}
else{
if(a>=7 && a<14){
8
}
else{
if(a>=14 && a<28){
9
}
else{
10
}
}
}
}
现在它有效,因为我们不是试图从函数中返回Int
,而是返回我们想要的整个函数。
答案 1 :(得分:1)
鉴于列类型为Long
,您的category
方法应采用Long
参数而不是Int
。以下是我如何定义函数:
def category: (Long => Long) = { a =>
if (a < 7) a else
if (a < 14) 8 else
if (a < 28) 9 else
10
}
val myudf = udf(category)
或者,您可以在一个代码块中创建UDF
:
val myudf = udf(
(a: Long) =>
if (a < 7) a else
if (a >= 7 && a < 14) 8 else
if (a >= 14 && a < 28) 9 else
10
)