我正在使用Scala编写Spark应用程序。我有以下两个RDD:
(a, 1, some_values1)
(b, 1, some_values2)
(c, 1, some_values3)
和
(a, 2, some_values1)
(b, 2, some_values2)
(a, 3, some_values1)
(b, 3, some_values2)
我正在尝试获取此输出:
(a, 1, 2, computed_values1)
(b, 1, 2, computed_values2)
(c, 1, 2, None)
(a, 1, 3, computed_values1)
(b, 1, 3, computed_values2)
(c, 1, 3, None)
因此,此处的字母用于将第一个RDD中的每个记录与第二个RDD中的记录进行匹配。我尝试使用join
方法,但对记录c
无效。我该如何实现?
更新
另一个例子:
(a, 1, some_values1)
(b, 1, some_values2)
(c, 1, some_values3)
和
(a, 2, some_values1)
(b, 2, some_values2)
(a, 3, some_values1)
(b, 3, some_values2)
(c, 3, some_values2)
我正在尝试获取此输出:
(a, 1, 2, computed_values1)
(b, 1, 2, computed_values2)
(c, 1, 2, None)
(a, 1, 3, computed_values1)
(b, 1, 3, computed_values2)
(c, 1, 3, computed_values3)
答案 0 :(得分:1)
如果我正确理解了您的要求,请采取以下方法:
rdd2c2
的第二列创建一个具有不同值的RDD,例如rdd2
cartesian join
和rdd1
上执行rdd2c2
,然后将结果转换为RDD [K,V]以构成the
的第一列和rdd2c2
列作为其key
rdd2
转换为RDD [K,V]以使其第一列和第二列作为其key
leftOuterJoin
并将元素转换为所需的结构示例代码:
val rdd1 = sc.parallelize(Seq(
("a", 1, "some_values1"),
("b", 1, "some_values2"),
("c", 1, "some_values3")
))
val rdd2 = sc.parallelize(Seq(
("a", 2, "some_values1"),
("b", 2, "some_values2"),
("a", 3, "some_values1"),
("b", 3, "some_values2"),
("c", 3, "some_values2")
))
val rdd2c2 = rdd2.map(_._2).distinct
// rdd2c2.collect: Array[Int] = Array(2, 3)
val rddKV1 = rdd1.cartesian(rdd2c2).
map{ case (a, b) => ((a._1, b), (a._2, a._3))}
// rddKV1.collect: Array[((String, Int), (Int, String))] = Array(
// ((a,2),(1,some_values1)),
// ((a,3),(1,some_values1)),
// ((b,2),(1,some_values2)),
// ((b,3),(1,some_values2)),
// ((c,2),(1,some_values3)),
// ((c,3),(1,some_values3)))
val rddKV2 = rdd2.map(r => ((r._1, r._2), r._3))
// rddKV2.collect: Array[((String, Int), String)] = Array(
// ((a,2),some_values1),
// ((b,2),some_values2),
// ((a,3),some_values1),
// ((b,3),some_values2),
// ((c,3),some_values2))
val rddJoined = rddKV1.leftOuterJoin(rddKV2).
map{ case (k, v) => (k._1, v._1._1, k._2, v._2) }
// rddJoined.collect: Array[(String, Int, Int, Option[String])] = Array(
// (a,1,3,Some(some_values1)),
// (a,1,2,Some(some_values1)),
// (c,1,2,None),
// (b,1,2,Some(some_values2)),
// (b,1,3,Some(some_values2)),
// (c,1,3,Some(some_values2)))
答案 1 :(得分:0)
如果只需要在结果中出现一次“ c”(猜测,期望的输出中打印错误),则可以使用以下代码来实现:
val data1 = List(
("a", 1, "some_values1"),
("b", 1, "some_values2"),
("c", 1, "some_values3")
)
val data2 = List(
("a", 2, "some_values1"),
("b", 2, "some_values2"),
("a", 3, "some_values1"),
("b", 3, "some_values2")
)
val rdd1 = sparkContext.parallelize(data1)
val rdd2 = sparkContext.parallelize(data2)
val rdd1WithKey = rdd1.map(v => (v._1, (v._2, v._3)))
val rdd2WithKey = rdd2.map(v => (v._1, (v._2, v._3)))
val joined = rdd1WithKey.fullOuterJoin(rdd2WithKey)
joined.foreach(println)
输出:
(b,(Some((1,some_values2)),Some((2,some_values2))))
(a,(Some((1,some_values1)),Some((2,some_values1))))
(b,(Some((1,some_values2)),Some((3,some_values2))))
(a,(Some((1,some_values1)),Some((3,some_values1))))
(c,(Some((1,some_values3)),None))