Apache spark 将二维结构数组取消测试为二维数组结构

Apache spark 将二维结构数组取消测试为二维数组结构,apache-spark,Apache Spark,我有一列类型为array 我想要一个struct类型的列。最短的解决方案是使用transform高阶函数(在Spark 2.4中介绍): ds.selectExpr( “将(structs,xs->transform(xs,x->x.foo))转换为foo”, 转换(结构,x->转换(x,x->x.bar))为条 ) 在旧版本中,您需要等效的udf*或使用键入的map: ds.as[Schema] .map(x=>( x、 structs.map(0.map(0.foo)), x、 结构映射(

我有一列类型为
array


我想要一个
struct类型的列。最短的解决方案是使用
transform
高阶函数(在Spark 2.4中介绍):

ds.selectExpr(
“将(structs,xs->transform(xs,x->x.foo))转换为foo”,
转换(结构,x->转换(x,x->x.bar))为条
)
在旧版本中,您需要等效的
udf
*或使用键入的
map

ds.as[Schema]
.map(x=>(
x、 structs.map(0.map(0.foo)),
x、 结构映射(0.map(0.bar))
)).toDF(“foo”、“bar”)
前一种解决方案可以概括为:

import org.apache.spark.sql.types.\u
导入org.apache.spark.sql.DataFrame
def expand(ds:DataFrame,col:String)={
val fields=ds.schema(col).dataType匹配{
案例ArrayType(ArrayType(s:StructType,,)=>s.FieldName
}
val exprs=fields.map{
字段=>expr(
s“转换(`$col`,xs->transform(xs,x->x.`$field`))为`$field`”
)
}
ds.select(表达式:*)
}
展开(ds.toDF,“结构”)
后一种方法可能不会太多,除非您想使用Scala反射(这是一种严重的过度使用)


*围绕这些线的一些东西应该能起到作用:

导入scala.reflect.runtime.universe.TypeTag
导入org.apache.spark.sql.functions.udf
def extract[T:TypeTag](字段:字符串)=udf(
(xs:Seq[Seq[Row]]=>xs.map(.map(.getAs[T](字段)))
)
val extractString=extract[String]_
val extractInt=extract[Int]_
选择(
提取字符串(“foo”)($“structs”)。作为(“foo”),
extractInt(“bar”)($“structs”).as(“bar”)
)
case class Struct(foo: String, bar: Int)
case class Schema(structs: Vector[Vector[Struct]])

val ss = spark
import ss.implicits._

val ds = Seq(Schema(Vector(Vector(Struct("a", 1), Struct("b", 2)), Vector(Struct("c", 3))))).toDS

val expected = Seq(
    (Vector(Vector("a", "b"), Vector("c")), Vector(Vector(1, 2), Vector(3)))
).toDF("foo", "bar")