apache-spark - Spark:Reduce() 与 Fold() 之间的区别
问题描述
我正在使用 Learning Spark,Lightning-Fast 数据分析书学习 Spark。
我去过很多网站并阅读了很多文章,但我仍然不明白 和 之间的reduce()
区别fold()
。
根据我正在使用的书:
“类似于reduce()
is fold()
,它也采用与所需签名相同的函数reduce()
,但另外采用“零值”用于每个分区的初始调用。您提供的零值应该是您的标识元素“
为了帮助我更好地理解,我运行以下代码:
rdd = sc.parallelize([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], 2)
rdd.getNumPartitions()
Out[1]: 2
rdd.glom().collect()
Out[2]: [[1, 2, 3, 4, 5], [6, 7, 8, 9, 10]]
rdd.reduce(lambda x,y: x+y)
Out[3]: 55
rdd.fold(0, lambda x,y: x+y)
Out[4]: 55
问题:1)引用:“但另外需要一个“零值”用于每个分区的初始调用。” 每个分区的初始调用是什么意思?
2)引用:“您提供的零值应该是您的操作的标识元素;也就是说,在您的函数中多次应用它不应该改变值”如果是这样,那么提供“值”的意义何在为手术?
3)根据我上面提供的例子,两者的总和都是55。有什么区别?
解决方案
不同之处在于 fold 允许您更改结果的类型,而 reduce 不能,因此可以使用数据中的值。例如
rdd.fold("",lambda x,y: x+str(y))
'12345678910'
您的示例不会更改结果的类型,实际上在该示例中,您可以使用 reduce 而不是 fold。
在非分布式环境中使用的“正常”折叠使用一次初始值。但是,当 spark 运行分布式时,它将运行一个折叠,该折叠将从每个分区中的初始值开始,然后在组合结果时再次运行因为在您的示例中,如果我们调用以下命令,您已经在 2 个分区中创建了上面的 10 个数字:
rdd.fold("HERE",lambda x,y: x+str(y))
我们会得到
'HEREHERE12345HERE678910'
推荐阅读
- python - Celery 未将消息发布到基于非任务的 RabbitMQ 队列
- sqlite - SQLite,ASCII 字符 0x20 到 0x7E 检查约束
- dockerfile - 删除 Dockerfile 中的 ADD
- swift - (NS)操作KVO依赖
- moodle - 登录无效,请从3.5.10升级到3.6.8后重试
- signalr - SignalR - 在连接时提示输入用户名和密码
- jestjs - 如何用酶测试反应钩
- google-apps-script - Google Script:在单元格中的日期前 7 天发送电子邮件
- laravel - 视图页面laravel中的未定义变量
- php - 替换除语言特定的所有特殊字符