在rdd int数组上执行求和

时间:2015-04-08 02:18:52

标签: apache-spark

是否存在任何内置转换以对以下rdd

的Int求和
org.apache.spark.rdd.RDD[(String, (Int, Int))]

string是键,Int数组是Value,我需要的是将所有Ints的总和作为RDD[(String, Int)]。我试过groupByKey没有成功......

此外 - 结果集必须再次为rdd。

提前致谢

2 个答案:

答案 0 :(得分:5)

如果目标是对值元素(Int,Int)求和,那么地图转换可以实现它:

val arr = Array(("A", (1, 1)), ("B", (2, 2)), ("C", (3, 3))

val rdd = sc.parallelize(arr)

val result = rdd.map{ case (a, (b, c)) => (a, b + c) }

// result.collect = Array((A,2), (B,4), (C,6))

如果值类型是数组,则可以使用Array.sum。

val rdd = sc.parallelize(Array(("A", Array(1, 1)), 
                               ("B", Array(2, 2)), 
                               ("C", Array(3, 3)))

rdd.map { case (a, b) => (a, b.sum) }

修改

map转换不保留原始分区,因为@Justin建议mapValues可能更合适:

rdd.mapValues{ case (x, y) => x + y }
rdd.mapValues(_.sum) 

答案 1 :(得分:2)

pyspark中有以下几种方式。

rdd = sc.parallelize([ ('A', (1,1)), ('B', (2,2)), ('C', (3, 3)) ])
rdd.mapValues(lambda (v1, v2): v1+v2).collect()

>>> rdd.map(lambda (k, v): (k, sum(v))).collect()
[('A', 2), ('B', 4), ('C', 6)]

或者

>>> rdd.map(lambda (k, v): (k, (v[0] + v[1]))).collect()
[('A', 2), ('B', 4), ('C', 6)]

或者

>>> def fn(x):
...   k_s = (x[0], sum(x[1]))
...   print k_s
... 
>>> rdd.foreach(fn)
('C', 6)
('A', 2)
('B', 4)