使用apache Spark结合元组列表

时间:2014-06-23 09:54:59

标签: scala apache-spark

我正试图加入RDD:

val u1 = sc.parallelize(List ( ("a" , (1,2)) , ("b" , (1,2))))
val u2 = sc.parallelize(List ( ("a" , ("3")) , ("b" , (2))))

我收到错误:

 scala> u1 union u2
<console>:17: error: type mismatch;
 found   : org.apache.spark.rdd.RDD[(String, Any)]
 required: org.apache.spark.rdd.RDD[(String, (Int, Int))]
Note: (String, Any) >: (String, (Int, Int)), but class RDD is invariant in type
T.
You may wish to define T as -T instead. (SLS 4.5)
              u1 union u2
                       ^

上面每个元组中的String类型都是一个键。

是否可以将这两种类型联合起来?

一旦联合u1和u2,我打算使用groupBy根据其密钥对每个项目进行分组。

2 个答案:

答案 0 :(得分:4)

您面临的问题实际上是由编译器解释的:您正尝试将(Int,Int)类型的值与值Any的值联接起来。 Any在此声明中是StringInt的超类:sc.parallelize(List ( ("a" , ("3")) , ("b" , (2))))。这可能是错误或可能是有意的。

在任何情况下,我都会尝试在联合之前使值收敛到一个公共类型。 鉴于Tuple1,Tuple2是不同的类型,我考虑更容易转换的其他容器。

假设上面的"3"实际上是3Int):

val au1 = sc.parallelize(List ( ("a" , Array(1,2)) , ("b" , Array(1,2))))
val au2 = sc.parallelize(List ( ("a" , Array(3)) , ("b" , Array(2))))
au1 union au2
org.apache.spark.rdd.RDD[(String, Array[Int])] = UnionRDD[10] at union at <console>:17
res: Array[(String, Array[Int])] = Array((a,Array(1, 2)), (b,Array(1, 2)), (a,Array(3)), (b,Array(2)))
  

一旦u1和u2联合起来,我打算使用groupBy对每个项目进行分组   根据它的关键。

如果您打算按键对两个rdds进行分组,可以考虑使用join代替union。这可以立即完成工作

au1 join au2
res: Array[(String, (Array[Int], Array[Int]))] = Array((a,(Array(1, 2),Array(3))), (b,(Array(1, 2),Array(2))))

如果上面的"3"实际上是"3"String):我考虑首先将值映射到公共类型。所有字符串或所有整数。与Any类型相比,它将使数据更易于操作。你的生活会更轻松。

答案 1 :(得分:1)

如果你想使用任何值的(键,值)RDD(我看到你正在尝试和RDD使用和(Int,Int),以及Int和一个字符串),你可以定义你的RDD的类型创建:

val u1:org.apache.spark.rdd.RDD[(String, Any)] = sc.parallelize(List ( ("a" , (1,2)) , ("b" , (1,2))))
val u2org.apache.spark.rdd.RDD[(String, Any)] = sc.parallelize(List ( ("a" , ("3")) , ("b" , (2))))

然后联盟将起作用,因为它是相同类型之间的联合。

希望有所帮助