我使用Spark和Scala进行一些数据处理。我有XML数据映射到dataframe。我将一行作为参数传递给UDF并尝试将两个复杂类型对象作为列表提取。 Spark给了我以下错误:
线程中的异常" main" java.lang.UnsupportedOperationException:不支持类型为org.apache.spark.sql.Row的模式
def testUdf = udf((testInput: Row) => {
val firstObject = testInput.getAs[Row]("Object1")
val secondObject = testInput.getAs[Row]("Object2")
val returnObject = Seq[firstObject,secondObject]
returnObject
})
你能告诉我我做错了吗?感谢。
答案 0 :(得分:2)
UDF无法返回Row
个对象。返回类型必须是Data Types table中Scala列值类型中枚举的类型之一。
好消息是这里不需要UDF。如果Object1
和Object2
具有相同的架构(无论如何都不会起作用),您可以使用array
函数:
import org.apache.spark.sql.functions._
df.select(array(col("Object1"), col("Object2"))
或
df.select(array(col("path.to.Object1"), col("path.to.Object2"))
如果Object1
和Object2
不是顶级列。
答案 1 :(得分:0)
我想建议一种替代方法,如果object1和object2的架构不同并且您可以返回该行,则可以使用该方法。 基本上要返回row,您只需返回一个具有Row对象架构的case类,在这种情况下,它们是object1和object2,它们本身似乎是行
执行以下操作
case class Object1(<add the schema here>)
case class Object2(<add the schema here>)
case class Record(object1:Object1,object2:Object2)
现在在UDF中,您可以使用firstObject和secondObject来创建object1和object2
然后
val record = Record(object1,object2)
然后您可以返回record
在这种情况下,即使架构不相同或需要进行一些处理,您也可以返回行。
我知道这实际上与您的问题无关,但是这个问题似乎是一个正确的机会来介绍这个概念。