这个python3程序试图使用map / reduce从文本文件中生成单词的频率列表。我想知道如何订购字数,表示为' count'在第二个reducer的yield语句中,最大计数值最后出现。目前,结果的尾部看起来像这样:
"0002" "wouldn"
"0002" "wrap"
"0002" "x"
"0002" "xxx"
"0002" "young"
"0002" "zone"
对于上下文,我将任何单词文本文件传递给python3程序,如下所示:
python MapReduceWordFreqCounter.py book.txt
以下是MapReduceWordFreqCounter.py
的代码:
from mrjob.job import MRJob
from mrjob.step import MRStep
import re
# ignore whitespace characters
WORD_REGEXP = re.compile(r"[\w']+")
class MapReduceWordFreqCounter(MRJob):
def steps(self):
return [
MRStep(mapper=self.mapper_get_words,
reducer=self.reducer_count_words),
MRStep(mapper=self.mapper_make_counts_key,
reducer = self.reducer_output_words)
]
def mapper_get_words(self, _, line):
words = WORD_REGEXP.findall(line)
for word in words:
yield word.lower(), 1
def reducer_count_words(self, word, values):
yield word, sum(values)
def mapper_make_counts_key(self, word, count):
yield str(count).rjust(4,'0'), word
def reducer_output_words(self, count, words):
for word in words:
yield count, word
if __name__ == '__main__':
MapReduceWordFreqCounter.run()
答案 0 :(得分:1)
您必须为您的工作设置自定义排序比较器。
如果你用java编写它,它看起来像
job.setSortComparatorClass(SortKeyComparator.class);
你必须提供一个提供逆序的课程
public class SortKeyComparator extends Text.Comparator {
@Override
public int compare(byte[] b1, int s1, int l1, byte[] b2, int s2, int l2) {
return (-1) * super.compare(b1, s1, l1, b2, s2, l2);
}
}
我猜python hadoop api有一些类似的方法来做这个技巧。
答案 1 :(得分:0)
对于MRJob Reduce步骤,不期望结果应按键'count'排序。
此处,MRJob导入允许您在本地和AWS Elastic MapReduce群集上运行代码。 MRJob执行繁重的工作,因为它使用Yarn API和Hadoop流在地图和减少作业之间进行分布式数据传输。
例如,要在本地运行,您可以将此MRJob运行为: python MapReduceWordFreqCounter.py books.txt> counts.txt
要在单个EMR节点上运行: python MapReduceWordFreqCounter.py -r emr books.txt> counts.txt
在25个EMR节点上运行: python MapReduceWordFreqCounter.py -r emr --num-ec2-instances = 25 books.txt> counts.txt
对分布式EMR作业进行故障排除(替换您的作业ID): python -m mrjob.tools.emr.fetch_logs --find-failure j-1NXEMBAEQFDFT
这里,当在四个节点上运行时,减少的结果是有序的,但在输出文件中有四个不同的部分。事实证明,强制减速器生成单个有序文件与在运行后作业步骤中排序结果相比,没有性能优势。因此,解决此特定问题的一种方法是使用Linux命令sort:
sort word_frequency_list.txt > sorted_word_frequency_list.txt
产生这些“尾”结果:
“0970”“的” “1191”“一个” “1292”“the” “1420”“你的” “1561”“你” “1828”“到”
更一般地说,Hadoop之上的框架是这种处理的理想选择。对于此问题,可以使用Pig读取已处理的文件并对计数进行排序。
Pig可以通过Grunt shell或Pig脚本运行(使用区分大小写的Pig Latin语法)。 Pig脚本遵循以下模板: 1)读取数据的LOAD语句 2)处理数据的一系列“转换”语句 3)用于保存结果的DUMP / STORE语句
使用猪订购计数:
reducer_count_output = LOAD 'word_frequency_list.txt' using PigStorage(' ') AS (word_count:chararray, word_name:chararray);
counts_words_ordered = ORDER reducer_count_output BY word_count ASC;
STORE counts_words_ordered INTO 'counts_words_ordered' USING PigStorage(':', '-schema');