如何在保留顺序的同时将RDD的内容替换为另一个?

时间:2016-01-05 11:24:22

标签: apache-spark

我有两个RDD,一个是(a, b, a, c, b, c, a),另一个是配对的RDD ((a, 0), (b, 1), (c, 2))

我想将第一个RDD中的abc替换为0,1,2(分别是键a,b,c的值)在第二个RDD)中。我想在第一个RDD中保留事件的顺序。

如何在Spark中实现它?

2 个答案:

答案 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映射很小,broadcastmap可能会更快:

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}