Python pySpark:reduceByKey运行总计算

时间:2017-04-16 17:42:15

标签: python pyspark

我有一个联接后的元组列表,看起来与此类似

                        [(u'something1', u'500'),
                         (u'something1', u'200'),
                         (u'something1', u'300'),
                         (u'something2', u'200'),
                         (u'something2', u'600'),
                         (u'something2', u'400')]

元组开头的U我相信代表一个Unicode字符

我已经在pySpark中编写了一个函数来进行计算,得到这样的结果。该函数基本上需要总结每个键

的总计数
              (something1, 1000),
               (something2, 1200)

这是我的功能

                 def calc_counts(a, b)
                     return a+b

然后我做了

              joined_data.reduceByKey(calc_counts).collect()

这给了我一个跨越10行的数字                    (你' something1,1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111,)

如何重新编写该函数calc_counts。

注意:我可能无法导入任何库,因为这是在控制台上执行而不是存储的python文件。

2 个答案:

答案 0 :(得分:1)

如果您已经使用了spark,那么使用现有的apis可以非常简单地实现您想要实现的目标。为已经工作的api编写自己的函数没有意义。

我假设,您在加入后的数据如下 -

data =    [(u'something1', u'500'),
            (u'something1', u'200'),
            (u'something1', u'300'),
            (u'something2', u'200'),
            (u'something2', u'600'),
            (u'something2', u'400')]

rdd = sc.parallelize(data)

查找每个密钥发生的总计数的总和,您只需要做 -

rdd \
.mapValues(lambda x : int(x)) \
.reduceByKey(lambda x,y : x+y) \
.collect()

此处,mapValues会将当前处于字符串格式u'500'的值转换为整数500,而匿名函数lambda x,y : x+y将汇总所有键的所有值。

答案 1 :(得分:1)

这是一种替代解决方案,您也可以使用groupby按第一个键分组并将每个组合并在一起

from pyspark.sql import Row
rdd = spark.sparkContext.parallelize([
    (u'something1', u'500'),
    (u'something1', u'200'),
    (u'something1', u'300'),
    (u'something2', u'200'),
    (u'something2', u'600'),
    (u'something2', u'400')])

out = rdd.groupBy(lambda x: x[0]).map(lambda x: Row(**{'key': x[0], 'sum': sum([int(e[1]) for e in x[1]])})).collect()

out Row

的列表
[Row(key='something2', sum=1200), Row(key='something1', sum=1000)]