在Spark中创建UDF时出错

时间:2018-01-16 06:58:02

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

我正在尝试使用以下代码在Spark中创建UDF

val makeSIfTesla = udf {(make: BigInt) => if(make == 0) 1 else make}

但是我收到以下错误:

java.lang.UnsupportedOperationException: Schema for type Any is not supported

为什么?

2 个答案:

答案 0 :(得分:1)

您收到错误是因为您将1作为整数返回。此外,配置单元中的bigint实际上是Long。因此,您的else正在返回Long,而您的if返回Int,这会产生您的UDF Any的返回类型,而Spark DataFrame不支持。 Here's a list of supported datatypes

如果您使用df.schema,它会告诉您实际需要的是LongType

val df = sqlContext.sql(" select cast(2 as bigint) as a ")
// df: org.apache.spark.sql.DataFrame = [a: bigint]

df.printSchema
// root
//  |-- a: long (nullable = false)


df.schema
// res16: org.apache.spark.sql.types.StructType = StructType(StructField(a,LongType,false))

您的UDF应该类似于:

val makeSIfTesla = udf {(make: Long) => if(make == 0) 1.toLong else make}
//makeSIfTesla : UserDefinedFunction = UserDefinedFunction(<function1>,LongType,List(LongType))

然而,对于像这样简单的事情,你真的不需要UDF。您可以使用Spark中提供的when-otherwise构造。

df.withColumn("x" , when($"x" === lit(0) , lit(1) ).otherwise($"x") )

其中x是您要传递到UDF makeSIfTesla的列。

答案 1 :(得分:0)

修复如下代码:

val makeSIfTesla = udf {(make: BigInt) => if(make == 0) BigInt(1) else make}

问题是1IntmakeBigInt,因此udf中的方法返回Any。 udf函数不支持Any,因此您看到错误。使类型保持一致使方法返回BigInt并修复问题。您还可以make的{​​{1}}

类型