我正在尝试使用以下代码在Spark中创建UDF
val makeSIfTesla = udf {(make: BigInt) => if(make == 0) 1 else make}
但是我收到以下错误:
java.lang.UnsupportedOperationException: Schema for type Any is not supported
为什么?
答案 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}
问题是1
为Int
,make
为BigInt
,因此udf中的方法返回Any
。 udf函数不支持Any
,因此您看到错误。使类型保持一致使方法返回BigInt
并修复问题。您还可以make
的{{1}}