rob*_*nki 0 scala apache-spark
我正在使用 Spark 和 Scala。我有两个 Pair RDD。
rdd1 : RDD[(String, List[String])]
rdd2 : RDD[(String, List[String])]
Run Code Online (Sandbox Code Playgroud)
两个 RDD 都连接到它们的第一个值。
val joinedRdd = rdd1.join(rdd2)
Run Code Online (Sandbox Code Playgroud)
因此生成的 RDD 的类型为RDD[(String, (List[String], List[String]))]。我想映射这个 RDD 并提取两个列表的元素,以便生成的 RDD 只包含两个列表的这些元素。
rdd1 (id, List(a, b))
rdd2 (id, List(d, e, f))
wantedResult (a, b, d, e, f)
Run Code Online (Sandbox Code Playgroud)
我天真的方法是直接用 来寻址每个元素(i),如下所示:
val rdd = rdd1.join(rdd2)
.map({ case (id, lists) =>
(lists._1(0), lists._1(1), lists._2(0), lists._2(2), lists._2(3)) })
/* results in RDD[(String, String, String, String, String)] */
Run Code Online (Sandbox Code Playgroud)
有没有办法获取每个列表的元素,而无需单独处理每个元素?类似“ lists._1.extractAll”的东西。有没有办法用来flatMap实现我想要实现的目标?
您可以简单地使用++运算符连接两个列表:
val res: RDD[List[String]] = rdd1.join(rdd2)
.map { case (_, (list1, list2)) => list1 ++ list2 }
Run Code Online (Sandbox Code Playgroud)
可能避免携带List[String]可能非常大的更好的方法是将RDD 分解为较小的(键值)对,将它们连接起来,然后执行以下操作groupByKey:
val flatten1: RDD[(String, String)] = rdd1.flatMapValues(identity)
val flatten2: RDD[(String, String)] = rdd2.flatMapValues(identity)
val res: RDD[Iterable[String]] = (flatten1 ++ flatten2).groupByKey.values
Run Code Online (Sandbox Code Playgroud)