可以用reduceBykey来改变类型和组合值 - Scala Spark?

时间:2014-12-17 21:21:06

标签: scala apache-spark rdd

在下面的代码中,我试图合并值:

val rdd: org.apache.spark.rdd.RDD[((String), Double)] =
    sc.parallelize(List(
      (("a"), 1.0),
      (("a"), 3.0),
      (("a"), 2.0)
      ))

val reduceByKey = rdd.reduceByKey((a , b) => String.valueOf(a) + String.valueOf(b))

reduceByValue应包含(a,1,3,2)但接收编译时错误:

Multiple markers at this line - type mismatch; found : String required: Double - type mismatch; found : String 
 required: Double

什么决定了reduce函数的类型?可以转换类型吗?

我可以使用groupByKey来获得相同的结果,但只想了解reduceByKey

2 个答案:

答案 0 :(得分:7)

不,给定RDD[(K,V)]类型的rdd,reduceByKey将采用类型为(V,V) => V的关联函数。

如果我们想要应用将值类型更改为其他任意类型的缩减,那么我们可以使用aggregateByKey

def aggregateByKey[U](zeroValue: U)(seqOp: (U, V) ⇒ U, combOp: (U, U) ⇒ U)

使用zeroValueseqOp函数,它在地图一侧提供类似折叠的操作,而关联函数combOpseqOp的结果组合在一起最后的结果,就像reduceByKey一样。 我们可以从签名中理解,虽然集合值的类型为V,但aggregateByKey的结果将是任意类型U

应用于上面的示例,aggregateByKey将如下所示:

rdd.aggregateByKey("")({case (aggr , value) => aggr + String.valueOf(value)}, (aggr1, aggr2) => aggr1 + aggr2)

答案 1 :(得分:1)

您的代码存在的问题是您的值类型不匹配。如果您更改了RDD中的值类型,则可以使用reduceByKey实现相同的输出。

val rdd: org.apache.spark.rdd.RDD[((String), String)] =
    sc.parallelize(List(
      ("a", "1.0"),
      ("a", "3.0"),
      ("a", "2.0")
      ))

    val reduceByKey = rdd.reduceByKey((a , b) => a.concat(b))

这是相同的例子。只要传递给reduceByKey的函数接受Value类型的两个参数(在你的情况下为Double)并返回相同类型的单个参数,你的reduceByKey就可以工作。