使用flatMapGroups时键入问题

时间:2017-03-15 20:11:49

标签: scala apache-spark spark-dataframe apache-spark-2.0 apache-spark-dataset

我正在将spark-1.6 rdd转换为spark-2.x数据集

原始代码是:

val sample_data : Dataset[(Int, Array[Double])]
val samples : Array[Array[Array[Double]]] = sample_data.rdd
  .groupBy(x => x._1)
  .map(x => {
   val (id: Int, points: Iterable[(Int, Array[Double])]) = x
   val data1 = points.map(x => x._2).toArray
   data1
}).collect()

sample_data.rdd不再有效,所以我尝试使用数据集执行相同的操作。新方法使用flatMapGroups

val sample_data : Dataset[(Int, Array[Double])]
val samples : Array[Array[Array[Double]]] = sample_data
  .groupByKey(x => x._1)
  .flatMapGroups ( (id: Int, points: Iterable[(Int, Array[Double])]) =>
    Iterator(points.map((x:Int, y:Array[Double]) => y)).toList
  ).collect()

给出的错误是:

  

错误:(36,25)重载的方法值映射与替代方案:[B,   那个](f:((Int,Array [Double]))=> B)(隐式bf:   scala.collection.generic.CanBuildFrom [可迭代[(中间体,   数组[双])],B,那]] [B](f:((Int,Array [Double]))=>   B)迭代器[B]不能应用于((Int,Array [Double])=>   阵列[双])           迭代器(points.map((x:Int,y:Array [Double])    => Y))。toList

请举例说明如何使用flatMapGroups以及如何理解给定的错误?

1 个答案:

答案 0 :(得分:1)

points实际上是Iterator,但是您将它投射到Iterable,因此编译器会告诉您将其设为Iterator

这就是你要做的事情:

val samples: Array[Array[Array[Double]]] = sample_data
    .groupByKey(_._1)
    .flatMapGroups((id: Int, points: Iterator[(Int, Array[Double])]) =>
        Iterator(points.map(_._2).toArray)
    ).collect()

在Iterator中重新打包并不是为了你的目的,所以你可以像这样使用mapGroup:

.mapGroups((_, points) => points.map(_._2).toArray)

但是在这两种情况下,Array [Array [_]]都没有编码器。查看here了解更多详情。

所以要么自己实现隐式编码器(existing Encoders),要么坚持RDD接口。