Scala-如何从DataFrame转换为Array [caseclass]

问题描述

我正在使用DataBricks处理数据。

DataFrame中的一列是数组。我想提取它以便可以处理它,但是语法有问题。我似乎仍将其提取为DataFrame而不是转换为Array

这里是一个例子。我的数据是一组动物。每只动物都有一个名字和一组动作。

我定义了两个Case类来保存数据

case class Movement ( 
  location: String,direction: String
)

case class Animal(
  var name: String,var movements: Array[Movement]
)

我定义了戈登和戴维这两只动物的数据

val m1 = Movement( "farm1","arrive");
val m2 = Movement( "farm1","leave");
val m3 = Movement( "farm2","arrive");
val m4 = Movement( "farm3","arrive");

val am = Array( m1,m2,m3);
val am2 = Array( m1,m4);
val df : Animal = Animal("Gordon",am )
val df2 : Animal = Animal( "David",am2 )
val df3 = Seq( df,df2 ).toDF;

我有一个处理动作的例程。为简化起见,在此示例中,仅显示了它们

def showMoves( amIn: Array[Movement]) {
  for( mv <- amIn ) (
    println( mv.location + " " + mv.direction )
  )
}

这对于戈登和戴维的运动非常有用

showMoves( am )
showMoves( am2 )

结果是:

farm1 arrive
farm1 leave
farm2 arrive

farm1 arrive
farm1 leave
farm3 arrive

这是所有已设置的数据。

现在,我决定我只对Gordon感兴趣,并想提取他的动作

val df4 = df3.filter( "name == 'Gordon'")
var am3 = df4.select("movements").as[Array[Movement]]

斯卡拉告诉我:

am3:org.apache.spark.sql.Dataset[Array[Movement]] = [movements: array]

我现在要处理他的动作,这就是问题所在。

showMoves( am3 )

斯卡拉告诉了我

command-721439694904705:44: error: type mismatch;
 found   : org.apache.spark.sql.Dataset[Array[Movement]]
 required: Array[Movement]
showMoves( am3 )

因此,据我了解,我已经将am3创建为Dataset [Array [Movement]]而不是Array [Movement],但是我无法解决的是如何以正确的类型创建am3。

解决方法

您应该使用collectAsList函数将数据框转换为数组,然后将其映射到移动数组。 这样做时,您会将所有数据收集到主节点。因此,如果数据繁重,则可能会出现oom错误。
所以代替

sudo service docker start

您应该使用

var am3 = df4.select("movements").as[Array[Movement]]