繁体   English   中英

Spark:如何在需要访问另一个RDD时映射RDD

[英]Spark: How to map an RDD when access to another RDD is required

给定两个大的键值对RDD( d1d2 ),两者都由唯一的ID键和矢量值组成(例如RDD[Int,DenseVector] ),我需要映射d1以便为其每个元素获取ID使用矢量之间的欧氏距离度量在d2最接近的元素。

我还没有找到使用标准RDD转换的方法。 我知道Spark中不允许嵌套的RDD,但是,如果可能的话,一个简单的解决方案是:

d1.map((k,v) => (k, d2.map{case (k2, v2) => val diff = (v - v2); (k2, sqrt(diff dot diff))} 
                      .takeOrdered(1)(Ordering.by[(Double,Double), Double](_._2))      
                      ._1))

此外,如果d1很小,我可以使用Map(例如d1.collectAsMap() )并遍历其每个元素,但由于数据集大小,这不是一个选项。

在Spark中有这种转换的替代方案吗?

编辑1:

使用@holden和@ david-griffin建议我使用cartesian()reduceByKey()解决了这个问题。 这是脚本(假设scSparkContext并使用Breeze库)。

val d1 = sc.parallelize(List((1,DenseVector(0.0,0.0)), (2,DenseVector(1.0,0.0)), (3,DenseVector(0.0,1.0))))
val d2 = sc.parallelize(List((1,DenseVector(0.0,0.75)), (2,DenseVector(0.0,0.25)), (3,DenseVector(1.0,1.0)), (4,DenseVector(0.75,0.0))))

val d1Xd2 = d1.cartesian(d2)
val pairDistances = d1Xd2.map{case ((k1, v1), (k2, v2)) => (k1, (k2, sqrt(sum(pow(v1-v2,2)))))}
val closestPoints = pairDistances.reduceByKey{case (x, y) => if (x._2 < y._2) x else y }

closestPoints.foreach(s => println(s._1 + " -> " + s._2._1))

获得的输出是:

1 -> 2
2 -> 4
3 -> 1

RDD上的转换只能应用于驱动程序端,因此嵌套映射将不起作用。 正如@davidgriffin指出你可以使用cartesian 对于您的用例,您可能希望使用reduceByKey跟随它,并且在您的reduce by键中,您可以跟踪最小距离。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM