我正试图加入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根据其密钥对每个项目进行分组。
答案 0 :(得分:4)
您面临的问题实际上是由编译器解释的:您正尝试将(Int,Int)
类型的值与值Any
的值联接起来。 Any
在此声明中是String
和Int
的超类:sc.parallelize(List ( ("a" , ("3")) , ("b" , (2))))
。这可能是错误或可能是有意的。
在任何情况下,我都会尝试在联合之前使值收敛到一个公共类型。 鉴于Tuple1,Tuple2是不同的类型,我考虑更容易转换的其他容器。
假设上面的"3"
实际上是3
(Int
):
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))))
然后联盟将起作用,因为它是相同类型之间的联合。
希望有所帮助