您现在的位置是:主页 > news > 网站开发 小程序开发/seo研究中心vip教程
网站开发 小程序开发/seo研究中心vip教程
admin2025/5/10 0:52:28【news】
简介网站开发 小程序开发,seo研究中心vip教程,wordpress 虚拟币,深圳专业建网站公司mapreduce练习在上一期《编程风格练习》中,我们使用Hazelcast库解决了词频问题。 这次,我们将为此使用MapReduce方法。 这是《编程风格练习》重点系列的第 19 个帖子。其他帖子包括: 以编程风格介绍练习 以编程风格进行练习,将内…
mapreduce练习
在上一期《编程风格练习》中,我们使用Hazelcast库解决了词频问题。 这次,我们将为此使用MapReduce方法。
这是《编程风格练习》重点系列的第 19 个帖子。其他帖子包括:
- 以编程风格介绍练习
- 以编程风格进行练习,将内容堆叠起来
- 编程风格的练习,Kwisatz Haderach风格
- 编程风格的练习,递归
- 具有高阶功能的编程风格的练习
- 以编程风格进行练习
- 以编程风格进行练习,回到面向对象的编程
- 编程风格的练习:地图也是对象
- 编程风格的练习:事件驱动的编程
- 编程风格的练习和事件总线
- 反思编程风格的练习
- 面向方面的编程风格的练习
- 编程风格的练习:FP&I / O
- 关系数据库风格的练习
- 编程风格的练习:电子表格
- 并发编程风格的练习
- 编程风格的练习:在线程之间共享数据
- 使用Hazelcast以编程风格进行练习
- MapReduce风格的练习 (本篇文章)
- 编程风格的练习总结
简而言之MapReduce
MapReduce是一个包含两个步骤的过程:
- Map :执行转换,过滤和分类为不同的“队列”
- 减少 :将“队列”的内容汇总到结果中
MapReduce的最大的好处是,既映射和减少步骤可以并行的两个潜在的执行。 这非常适合处理大型数据集。
下图有助于可视化整体流程:
虽然MapReduce使并行成为可能,但实现它不是强制性的: 并行只是一个选择 。 原始Python代码和Kotlin端口均未使用它。
迁移到Kotlin
参考代码使用Python yield
关键字:函数不会返回简单的项集合 ,而是返回流 。 尽管代码看起来完全一样,但实际情况却有所不同。 与标准集合相比,与流中关联的项目数成比例地提高了性能。 在Java中,使用Stream
实现Stream
,而在Kotlin中,使用Sequence
。
为此,Kotlin提供了Iterable<T>.asSequence()
扩展功能。 要更深入地了解Kotlin中的集合和序列,以及它们与Java流的关系,请查看此早期文章 。
应用于眼前的问题,处理管道如下所示:
这将转换为以下代码:
funrun(filename:String):Map<String,Int>=read(filename).asSequence().chunked(200).map(::splitWords).reduce{acc,pair->countWords(acc,pair)}.sortedBy{it.second}.takeLast(25).toMap()
还原概述
map()
函数已在本系列的先前文章中得到了充分使用。 此外,我相信大多数开发人员已经以某种方式熟悉它。
另一方面,即使使用了很多方法, reduce()
函数的理解也很少。 例如,在Java中,流的终端操作是归约函数:这些函数包括sum()
, average()
, max()
以及collect()
! 从collect()
Javadoc:
使用Collector
在此流的元素上执行可变还原操作。
收集函数只是Stream
提供的更通用的reduce()
函数的特化:
如图所示,减少有三种“味道”:
- 第一种形式接受单个
BinaryOperator
参数。BinaryOperator<T>
接受两个T
类型的参数,并将它们组合在一起以返回T
请注意,由于起始流可能为空,因此该方法返回Optional<T>
。例如,以下代码段汇总了流中的项目:
Stream.of(1,2,3,4,5).reduce{a,b->a+b}
- 第二种风味类似于第一种,但需要一个起始值。 因此,返回类型不是
Optional<T>
而是T
如果流为空,则结果将为起始值。 如果不是,它应该与先前的风味相同,但前提是起始值是还原功能的中性元素。Stream.of(1,2,3,4,5).reduce{a,b->a+b}
- 第三种也是最后一种风味允许以更复杂的代价更改返回的类型
在Kotlin中,还原与Java中的还原非常相似。 但是,有一点区别:接受起始值的函数称为fold()
,不接受的函数称为reduce()
。 另外,它们两个都还提供了另一个签名,该签名提供了当前项目的索引。
签名 | 起始值 | 索引 |
---|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
上面处理空序列的无起始值函数将在运行时引发异常。 这是我认为Kotlin API与Java相比显得苍白的少数地方之一。 我对Kotlin的Slack提出了要点,可能在stdlib的未来版本之一中引入了新的xxxOrNull()。
Kotlin中已实现的功能
映射函数仅从行列表中创建对数为1的单词对:
funsplitWords(lines:Iterable<String>):Iterable<Pair<String,Int>>{funIterable<String>.scan()=this.flatMap{it.toLowerCase().split("\\W|_".toRegex())}.filter{it.isNotBlank()&&it.length>=2}funIterable<String>.removeStopWords():Iterable<String>{valstopWords=read("stop_words.txt").flatMap{it.split(",")}returnthis-stopWords}returnlines.scan().removeStopWords().map{itto1}
}
我相信这很简单。 还原功能结合了字频率的两个iterables共同创造一个新的迭代。
funcountWords(frequencies1:Iterable<Pair<String,Int>>,frequencies2:Iterable<Pair<String,Int>>):Iterable<Pair<String,Int>>{valresults=mutableMapOf<String,Int>()frequencies1.forEach{results.merge(it.first,it.second){count,value->count+value}}frequencies2.forEach{results.merge(it.first,it.second){count,value->count+value}}returnresults.toList()
}
这很粗糙,但是行得通。 可悲的是,我发现没有其他优雅的方法可以实现合并。 提案欢迎!
一路上有点打ic
那可能是终点,但是不幸的是不是。 对于最小的数据集-每个单词的频率为一个,对于最大的数据集-自豪和偏见,大多数测试成功。 但是,它对于以下示例失败:
White tigers live mostly in India Wild lions live mostly in Africa
其背后的原因是,映射函数将默认频率分配为1,但是读取的行被分成大小为200的单词块(请参见上文)。 由于样本不够大,因此未应用 countWords()
减少函数 。 因此,单词对/ 1不会合并在一起,并且每个单词的结果映射图的频率为1。
为了返回正确的结果,应该先检查样本大小,然后再通过MapReduce流程将其发送出去。
结论
MapReduce没什么大不了的。 大多数开发人员已经在不知情的情况下使用它。 唯一的挑战是编码正确的映射和归约函数。
另外,应该特别注意输入的大小和处理方式,因为如果输入的大小太小,则不需要缩减函数,也不会执行其代码。 但是,在大多数情况下,这不应该成为问题,因为MapReduce的目标是大型数据集。
翻译自: https://blog.frankel.ch/exercises-programming-style/19/
mapreduce练习