如何使用具有((key1,value),(key2,value))模式的Apache Spark查找键的所有值的总和

时间:2016-04-02 23:10:38

标签: hadoop apache-spark pyspark

我的数据集如下 -

A  B  C
(a,c,30)
(a,b,20)
(b,c,10)
(c,d,1)

现在我需要处理上面的数据以获得像 - 的输出 A列中的任何键都将乘以C的2倍 并且B列中的任何键将乘以C的3倍

所以这里的预期输出将是 -

a   100      =30*2+20*2
b   80       =20*3+10*2
c   122      =30*3+10*3+1*2
d   3        =1*3 

我可以设法写下如下 -

val x = sc.parallelize(List(
  ("a","b",20),
  ("b","c",10),
  ("a","c",30),
  ("c","d",1)
))

val myVal = x.map({
  case (a,b,c) => ((a-> 2 * c), (b -> 3 * c))
})

myVal.foreach(println)

输出 -

((a,60),(c,90))
((c,2),(d,3))
((a,40),(b,60))
((b,20),(c,30))

之后我无法进一步打破它 如何使用spark scala获得预期的结果?

1 个答案:

答案 0 :(得分:3)

关键是先使它平坦 - 将一个值与一个键相关联。然后就可以使用reduceByKey操作来总结它。

我不是scala开发人员,但这样的事情可能会奏效。

myVal
  .flatMap({ case (a, b, c) => List(a -> 2 * c, b -> 3 * c) })
  .reduceByKey((a, b) => a + b)
  .foreach(println(_))

此处列出的是每次必须创建的其他对象,最好避免它。因此,这样的事情可能会起作用 - 查看数据两次,但之前将其缓存。

myVal.cache()
  .map({ case (a, b, c) => a -> 2 * c })
  .union(rdd.map({ case (a, b, c) => b -> 3 * c }))
  .reduceByKey((a, b) => a + b)
  .foreach(println(_))
myVal.unpersist()