mrjob:该示例如何自动知道如何在文本文件中查找行?

KJW*_*KJW 6 python mapreduce mrjob

我试图更好地理解 mrjob 的示例

from mrjob.job import MRJob  
class MRWordFrequencyCount(MRJob):

    def mapper(self, _, line):
        yield "chars", len(line)
        yield "words", len(line.split())
        yield "lines", 1

    def reducer(self, key, values):
        yield key, sum(values)
if __name__ == '__main__':
    MRWordFrequencyCount.run()
Run Code Online (Sandbox Code Playgroud)

我运行它

$ python word_count.py my_file.txt
Run Code Online (Sandbox Code Playgroud)

它按预期工作,但我不明白它如何自动知道它将读取文本文件并将其按行分割。我也不确定它是_做什么的。

据我了解,mapper()每行生成的三个键/值对是否正确?如果我想处理文件夹中的每个文件该怎么办?

并且reducer()自动知道如何将每个键的值相加?

如果我想通过 MapReduce 运行单元测试怎么办,Mapper 和Reducer 会是什么样子?有必要吗?

Tar*_*ato 5

映射器方法接收已经从输入文本中解析出来的键值对。mrjob 使用 Hadoop 流式处理,每个输入文本都除以换行符,然后根据使用的输入协议将每一行拆分为键值对。这是框架为您处理的事情,因此您不必做任何繁重的工作;您可以假设您将获得正确的密钥和值。

但是,您确实需要指定指定的输入文本文件类型。例如,如果键和/或值不是纯文本(如原始问题中所示)而是序列化 JSON,则您可以使用 JSONProtocol/JSONValueProtocol 等,而不是默认的 RawValueProtocol。

对于初始映射器,每一行都被读入值(通过 RawValueProtocol),因此这就是您没有收到密钥的原因。using_只是未使用的虚拟变量的 Python 约定。(然而,_实际上是 Python 变量的有效名称。你可以做这样的事情a = 3; _ = 2; b = a + _。亵渎,不是吗?)

mrjob 可以采用多个输入文件。例如你可以这样做

$ python wordcount.py text1.txt text2.txt
Run Code Online (Sandbox Code Playgroud)

如果您希望所有文本文件作为 mrjob 作业的输入,您可以执行以下操作

$ python wordcount.py inputdir/*.txt
Run Code Online (Sandbox Code Playgroud)

或者只是简单地

$ python wordcount.py inputdir
Run Code Online (Sandbox Code Playgroud)

并且所有选定的文件都用作输入。

减速器接收的是一个键和与该键关联的所有值的迭代器。values因此,如果举个例子, reducer 方法中的变量是一个迭代器。如果您想对所有值执行某些操作,则需要实际迭代所有值。在问题的具体示例中,内置函数sum可以将迭代器作为参数,这就是为什么您可以一次性完成它。但它实际上类似于sum([value for value in values]).

我实际上不知道如何对 mrjob 脚本进行单元测试。我通常在生产运行之前只测试一小块测试数据。