spark中的partitionBy和groupBy有什么区别

2024-09-29 06:32:32 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个pyspark rdd,它可以收集为元组列表,如下所示:

rdds = self.sc.parallelize([(("good", "spark"), 1), (("sood", "hpark"), 1), (("god", "spak"), 1),
                                (("food", "spark"), 1), (("fggood", "ssspark"), 1), (("xd", "hk"), 1),
                                (("good", "spark"), 7), (("good", "spark"), 3), (("good", "spark"), 4),
                                (("sood", "hpark"), 5), (("sood", "hpark"), 7), (("xd", "hk"), 2),
                                (("xd", "hk"), 1), (("fggood", "ssspark"), 2), (("fggood", "ssspark"), 1)], 6)
rdds.glom().collect()

def inner_map_1(p):
    d = defaultdict(int)
    for row in p:
        d[row[0]] += row[1]
    for item in d.items():
        yield item

rdd2 = rdds.partitionBy(4, partitionFunc=lambda x: hash(x)).mapPartitions(inner_map_1)
print(rdd2.glom().collect())

def inner_map_2(p):
    for row in p:
        item = row[0]
        sums = sum([num for _, num in row[1]])
        yield item, sums
rdd3 = rdds.groupBy(lambda x: x[0]).mapPartitions(inner_map_2)
print(rdd3.glom().collect())

rdd2和rdd3是以不同的形式计算的,我得到了相同的结果,但我不确定rdd2和rdd3得到的结果是否相同,元素是否在同一个分区中


Tags: inmapforitemsparkrowinnergood
2条回答

partitionBy通常意味着您将散列分区键并将它们发送到RDD的特定分区。这会将任何具有匹配键的内容合并到同一分区中,这在执行连接时非常有用,因为在同一位置需要所有匹配键。partitionBy不会丢弃任何记录,它只对匹配的键进行了冒号

df.partitionBy("vendorId") // all rows kept they are now colocated in the same rdd partition

groupBy是一个SQL概念。If查找该键的所有唯一键组合。您还可以对具有相同密钥的所有记录执行聚合函数。例如,如果您想用相同的键计算所有记录,您可以

df.groupBy("vendorId").count.show

这将统计具有相同供应商ID的所有记录。与partitionBy不同,groupBy倾向于大大减少记录数。(见基数)

我建议运行df.groupBy(“vendorId”)。解释(true)。这将打印出逻辑计划(考虑SQL等价项)和物理计划(spark将执行的确切操作集)。通常,spark将groupBy转换为部分哈希聚合->;洗牌(按键分区)——>;最终哈希聚合–>;结果

我想说,“groupBy”是一种更符合逻辑的数据分组方式。它看起来像SQL中的“groupBy”

“PartitionBy”更具物理性。您实际上是在集群中对数据进行物理分区

相关问题 更多 >