[英]Join on two RDDs using Scala in Spark
我正在嘗試在Spark上實現Local Outlier Factor。 因此,我從文件中讀取了一組點,然后為每個點找到N個最近的鄰居。 每個點都有一個使用zipWithIndex()命令指定的索引
所以現在我有兩個RDD
RDD[(Index:Long, Array[(NeighborIndex:Long, Distance:Double)])]
其中Long表示其索引,而Array由其N個最近的鄰居組成,Long表示這些鄰居的索引位置,而Double表示其與給定點的距離
第二
RDD[(Index:Long,LocalReachabilityDensity:Double)]
在這里,Long再次表示給定點的索引,Double表示其局部可到達性密度
我想要的是一個RDD,其中包含所有點,以及它們的N個最近鄰居及其本地可達性密度的數組
RDD[(Index:Long, Array[(NeighborIndex:Long,LocalReachabilityDensity:Double)])]
因此,基本上,這里Long將代表一個點的索引,而數組將是其N個最鄰近的鄰居,以及它們的索引值和Local Reachability density。
根據我的理解,我需要在第一個RDD上運行一個映射,然后將其數組中的值與包含本地可達性密度的第二個RDD聯接起來,以獲取其N個鄰居的所有給定索引的本地可達性密度。 但是我不確定如何實現這一目標。 如果有人可以幫助我,那將很棒
鑒於:
val rdd1: RDD[(index: Long, Array[(neighborIndex: Long, distance: Double)])] = ...
val rdd2: RDD[(index: Long, localReachabilityDensity: Double)] = ...
我真的根本不喜歡使用Scala的Array
。 我也不喜歡您的抽象是多用途的。 換句話說, index
在rdd2
被安葬在各個條目rdd1
。 這使事情變得難以推理,並且還引起了Spark RDD API的局限性,即在轉換第一個RDD時無法訪問第二個RDD。 我相信您應該重寫當前的工作以產生更容易使用的抽象。
但是,如果您必須:
val flipped = rdd1.map {
case (index, array) =>
array.map {
case (neighborIndex, distance) => (neighborIndex, (index, distance))
}.elements.toVector
}.flatMap(identity)
.groupBy(_._1)
val result = flipped.join(rdd2).mapValues {
case (indexDistances, localReachabilityDensity) =>
indexDistances.map {
case (index, _) => (index, localReachabilityDensity)
}
}
其基本思想是翻轉rdd1
為“提取”的neighborIndex
值到頂級的的按鍵PairRDD
,然后讓我做了join
與rdd2
。 並用Vector
替換Array
。 一旦對相同的索引進行聯接,合並起來就容易得多。
請注意,這超出了我的頭腦,可能並不完美。 這個主意並不是為您提供復制粘貼的解決方案,而是建議一個不同的方向。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.