[英]subsets manipulation on vectors in spark scala
我有以下形式的RDD curRdd
res10: org.apache.spark.rdd.RDD[(scala.collection.immutable.Vector[(Int, Int)], Int)] = ShuffledRDD[102]
與curRdd.collect()
產生以下結果。
Array((Vector((5,2)),1), (Vector((1,1)),2), (Vector((1,1), (5,2)),2))
此處鍵 :整數對的向量和值 :計數
現在,我想通過向下計數來將其轉換為RDD[(scala.collection.immutable.Vector[(Int, Int)], Int)]
形式的另一個RDD。
也就是說(Vector((1,1), (5,2)),2))
會將其2的計數貢獻給作為其子集的任何鍵,就像(Vector((5,2)),1)
變成(Vector((5,2)),3)
。
對於上面的示例,我們的新RDD將具有
(Vector((5,2)),3), (Vector((1,1)),4), (Vector((1,1), (5,2)),2)
我該如何實現? 請幫助。
首先,您可以介紹Seq
subsets
操作:
implicit class SubSetsOps[T](val elems: Seq[T]) extends AnyVal {
def subsets: Vector[Seq[T]] = elems match {
case Seq() => Vector(elems)
case elem +: rest => {
val recur = rest.subsets
recur ++ recur.map(elem +: _)
}
}
}
empty
集將始終是結果向量中的第一個元素,因此您可以使用.tail
忽略它
現在你的任務是很明顯的map
- reduce
其flatMap
- reduceByKey
來講RDD
:
val result = curRdd
.flatMap { case (keys, count) => keys.subsets.tail.map(_ -> count) }
.reduceByKey(_ + _)
此實現可能會在結果中引入新的集合,如果您只想選擇原始集合中存在的集合,則可以將結果與原始集合連接起來:
val result = curRdd
.flatMap { case (keys, count) => keys.subsets.tail.map(_ -> count) }
.reduceByKey(_ + _)
.join(curRdd map identity[(Seq[(Int, Int)], Int)])
.map { case (key, (v, _)) => (key, v) }
請注意,在原始RDD
需要map identity
步驟才能將鍵類型從Vector[_]
轉換為Seq[_]
。 相反,您可以修改SubSetsOps
定義,用Vector[T]
代替Seq[T]
所有出現,或按照以下(硬編碼scala.collection
)方式更改定義:
import scala.collection.SeqLike
import scala.collection.generic.CanBuildFrom
implicit class SubSetsOps[T, F[e] <: SeqLike[e, F[e]]](val elems: F[T]) extends AnyVal {
def subsets(implicit cbf: CanBuildFrom[F[T], T, F[T]]): Vector[F[T]] = elems match {
case Seq() => Vector(elems)
case elem +: rest => {
val recur = rest.subsets
recur ++ recur.map(elem +: _)
}
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.