pyspark RDD countByKey()如何计数?

时间:2019-02-03 18:30:36

标签: python apache-spark pyspark rdd

在发布此问题之前,我搜索了社区并引用了pyspark文档,但我仍然无法理解其计数方式。

sc.parallelize((('1',11),('1'),('11'),('11',1))).countByKey().items() 

输出:

dict_items([('1', 3), ('11', 1)])

我无法解释输出。为什么将“ 1”计为3,将“ 11”计为1?

2 个答案:

答案 0 :(得分:2)

调用countByKey()时,键将是传入的容器的第一个元素(通常是tuple),其余将是值。

您可以认为执行在功能上大致等同于:

from operator import add

def myCountByKey(rdd):
    return rdd.map(lambda row: (row[0], 1)).reduceByKey(add)

该函数将rdd中的每一行映射到该行的第一个元素(键),并以数字1作为值。最后,我们减少将每个键的值相加,以得到计数。

让我们在您的示例上尝试一下:

rdd = sc.parallelize((('1',11),('1'),('11'),('11',1)))
myCountByKey(rdd).collect()
#[('1', 3), ('11', 1)]

“额外” '1'来自第三个元素('11')。将此行映射到(row[0], 1)会产生('1', 1)。在这种情况下,row[0]是字符串中的第一个字符。

您可能希望它的行为就像第三个元素是元组('11',)

rdd = sc.parallelize((('1',11),('1',),('11',),('11',1)))
rdd.countByKey().items()
#[('1', 2), ('11', 2)]

要点是,如果要指定无值的键,则必须 包含逗号。

答案 1 :(得分:0)

就像是否执行默认拆分以获取元组数组一样: ((''1',11),('1'),('11'),('11',1)) 会变成 ((''1',11),('1',''),('1','1'),('11',1)) countByKey将导致: [('1','3'),('11','1')]