我正在将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以及如何理解给定的错误?
答案 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
接口。