我有两个RDD,一个是(a, b, a, c, b, c, a)
,另一个是配对的RDD ((a, 0), (b, 1), (c, 2))
。
我想将第一个RDD中的a
,b
和c
替换为0,1,2(分别是键a,b,c的值)在第二个RDD)中。我想在第一个RDD中保留事件的顺序。
如何在Spark中实现它?
答案 0 :(得分:5)
例如:
val rdd1 = sc.parallelize(Seq("a", "b", "a", "c", "b", "c", "a"))
val rdd2 = sc.parallelize(Seq(("a", 0), ("b", 1), ("c", 2)))
rdd1
.map((_, 1)) // Map first to PairwiseRDD with dummy values
.join(rdd2)
.map { case (_, (_, x)) => x } // Drop keys and dummy values
如果RDD映射很小,broadcast
和map
可能会更快:
val bd = sc.broadcast(rdd2.collectAsMap)
// This assumes all values are present. If not use get / getOrElse
// or map withDefault
rdd1.map(bd.value)
它还将保留元素的顺序。
如果是join
,您可以添加增加的标识符(zipWithIndex
/ zipWithUniqueId
),以便能够恢复初始订购,但实际上要贵得多。
答案 1 :(得分:1)
您可以使用join
。
首先模拟您的RDDs
:
val rdd = sc.parallelize(List("a","b","a","c","b","c","a"))
val mapping = sc.parallelize(List(("a",0),("b",1),("c",2)))
您只能加入pairRDDs
,因此请将原始rdd
映射到pairRDD
,然后加入mapping
rdd.map(s => (s, None)).join(mapping).map{case(_, (_, intValue)) => intValue}