我需要从另一个配对的RDD生成配对的RDD。基本上,我正在尝试编写一个执行以下操作的map函数。
RDD[Polygon,HashSet[Point]] => RDD[Polygon,Integer]
这是我写的代码:
Scala函数,它迭代HashSet并从“Point”对象中添加一个值。
def outCountPerCell( jr: Tuple2[Polygon,HashSet[Point]] ) : Tuple2[Polygon,Integer] = {
val setIter = jr._2.iterator()
var outageCnt: Int = 0
while(setIter.hasNext()) {
outageCnt += setIter.next().getCoordinate().getOrdinate(2).toInt
}
return Tuple2(jr._1,Integer.valueOf(outageCnt))
}
在配对的RDD上应用该功能,这会引发错误:
scala> val mappedJoinResult = joinResult.map((t: Tuple2[Polygon,HashSet[Point]]) => outCountPerCell(t))
<console>:82: error: type mismatch;
found : ((com.vividsolutions.jts.geom.Polygon, java.util.HashSet[com.vividsolutions.jts.geom.Point])) => (com.vividsolutions.jts.geom.Polygon, Integer)
required: org.apache.spark.api.java.function.Function[(com.vividsolutions.jts.geom.Polygon, java.util.HashSet[com.vividsolutions.jts.geom.Point]),?]
val mappedJoinResult = joinResult.map((t: Tuple2[Polygon,HashSet[Point]]) => outCountPerCell(t))
有人可以查看我看到的内容,或者分享在map()操作中使用自定义函数的任何示例代码。
答案 0 :(得分:2)
这里的问题是joinResult
是来自Java API的JavaPairRDD
。这个数据结构的map
期待Java类型lambdas(Function
),它们(至少可以轻易地)与Scala lambdas互换。
所以有两种解决方案:尝试将给定方法转换为Java Function
以传递给map
,或者只是像开发人员那样使用Scala RDD:
在这里,我创建一些替代类,并创建一个与OP的结构类似的Java RDD:
scala> case class Polygon(name: String)
defined class Polygon
scala> case class Point(ordinate: Int)
defined class Point
scala> :pa
// Entering paste mode (ctrl-D to finish)
/* More idiomatic method */
def outCountPerCell( jr: (Polygon,java.util.HashSet[Point])) : (Polygon, Integer) =
{
val count = jr._2.asScala.map(_.ordinate).sum
(jr._1, count)
}
// Exiting paste mode, now interpreting.
outCountPerCell: (jr: (Polygon, java.util.HashSet[Point]))(Polygon, Integer)
scala> val hs = new java.util.HashSet[Point]()
hs: java.util.HashSet[Point] = []
scala> hs.add(Point(2))
res13: Boolean = true
scala> hs.add(Point(3))
res14: Boolean = true
scala> val javaRDD = new JavaPairRDD(sc.parallelize(Seq((Polygon("a"), hs))))
javaRDD: org.apache.spark.api.java.JavaPairRDD[Polygon,java.util.HashSet[Point]] = org.apache.spark.api.java.JavaPairRDD@14fc37a
可以使用.rdd
:
scala> javaRDD.rdd.map(outCountPerCell).foreach(println)
(Polygon(a),5)
mapValues
与Scala RDD一起使用由于只有元组的第二部分正在改变,所以.mapValues
可以彻底解决这个问题:
scala> javaRDD.rdd.mapValues(_.asScala.map(_.ordinate).sum).foreach(println)
(Polygon(a),5)