簡體   English   中英

在Spark中使用Scala加入兩個RDD

[英]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 我也不喜歡您的抽象是多用途的。 換句話說, indexrdd2被安葬在各個條目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 ,然后讓我做了joinrdd2 並用Vector替換Array 一旦對相同的索引進行聯接,合並起來就容易得多。

請注意,這超出了我的頭腦,可能並不完美。 這個主意並不是為您提供復制粘貼的解決方案,而是建議一個不同的方向。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM