如何处理cogroup值?

时间:2015-10-01 17:13:30

标签: scala apache-spark

我正在组合两个RDD,我想处理它的值。也就是说,

rdd1.cogroup(rdd2)

作为这种合作的结果,我得到如下结果:

(ion,(CompactBuffer(100772C121, 100772C111, 6666666666),CompactBuffer(100772C121)))

考虑到这个结果,我想获得所有不同的对。 e.g。

关键词'

100772C121 - 100772C111
100772C121 - 666666666
100772C111 - 666666666

我如何在scala中执行此操作?

1 个答案:

答案 0 :(得分:2)

您可以尝试以下内容:

(l1 ++ l2).distinct.combinations(2).map { case Seq(x, y) => (x, y) }.toList

您需要为l1字段更新l2CompactBuffer。当我在本地尝试这个时,我得到了这个(我相信你想要的):

scala> val l1 = List("100772C121", "100772C111", "6666666666")
l1: List[String] = List(100772C121, 100772C111, 6666666666)

scala> val l2 = List("100772C121")
l2: List[String] = List(100772C121)

scala> val combine = (l1 ++ l2).distinct.combinations(2).map { case Seq(x, y) => (x, y) }.toList
combine: List[(String, String)] = List((100772C121,100772C111), (100772C121,6666666666), (100772C111,6666666666))

如果您希望所有这些对分开在不同的行上,则可以将此逻辑括在flatMap内。

编辑:为上面的示例添加了步骤。

scala> val rdd1 = sc.parallelize(Array(("ion", "100772C121"), ("ion", "100772C111"), ("ion", "6666666666")))
rdd1: org.apache.spark.rdd.RDD[(String, String)] = ParallelCollectionRDD[0] at parallelize at <console>:12

scala> val rdd2 = sc.parallelize(Array(("ion", "100772C121")))
rdd2: org.apache.spark.rdd.RDD[(String, String)] = ParallelCollectionRDD[1] at parallelize at <console>:12

scala>   val cgrp = rdd1.cogroup(rdd2).flatMap {
 |         case (key: String, (l1: Iterable[String], l2: Iterable[String])) =>
 |         (l1.toSeq ++ l2.toSeq).distinct.combinations(2).map { case Seq(x, y) => (x, y) }.toList
 |       }
 cgrp: org.apache.spark.rdd.RDD[(String, String)] = FlatMappedRDD[4] at flatMap at <console>:16

 scala> cgrp.foreach(println)

 ...

 (100772C121,100772C111)
 (100772C121,6666666666)
 (100772C111,6666666666)

编辑2:根据您的使用情况再次更新。

 scala> val cgrp = rdd1.cogroup(rdd2).flatMap {
 |      case (key: String, (l1: Iterable[String], l2: Iterable[String])) =>
 |           for { e1 <- l1.toSeq; e2 <- l2.toSeq; if (e1 != e2) } 
 |                yield if (e1 > e2) ((e1, e2), 1) else ((e2, e1), 1)
 |      }.reduceByKey(_ + _)

 ... 

 ((6666666666,100772C121),2)
 ((6666666666,100772C111),1)
 ((100772C121,100772C111),1)