Return 来自 Spark-Scala UDF 的 Seq[Row]

Return Seq[Row] from Spark-Scala UDF

我正在使用 Spark 和 Scala 进行一些数据处理。我有 XML 数据映射到数据框。我将一个 Row 作为参数传递给 UDF,并尝试将两个复杂类型的对象提取为一个列表。 Spark 给我以下错误:

Exception in thread "main" java.lang.UnsupportedOperationException: Schema for type org.apache.spark.sql.Row is not supported

def testUdf = udf((testInput: Row) => {
  val firstObject = testInput.getAs[Row]("Object1")
  val secondObject = testInput.getAs[Row]("Object2")
  val returnObject = Seq[firstObject,secondObject]

  returnObject
})

你能告诉我我做错了什么吗?谢谢

UDF 不能 return Row 对象。 Return 类型必须是 Data Types table 中 Scala 的值类型列中枚举的类型之一。

好消息是这里应该不需要 UDF。如果 Object1Object2 具有相同的架构 (无论如何它都不会工作)你可以使用 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"))

如果 Object1Object2 不是顶级列。

我想建议一种替代方法,如果 object1 和 object2 的架构不同并且您到达 return 行,则可以使用该方法。 基本上 return 行,你只是 return 一个案例 class 具有 Row 对象的模式,在这种情况下是 object1 和 object2,它们本身似乎是 rows

请执行以下操作

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)

然后你可以return record

即使架构不同或需要一些处理,您也可以在其中 return 行。

我知道这实际上与您的问题无关,但这个问题似乎是讲述这个概念的正确机会。