在 Python 中执行 mapreduce 函数

Performing a mapreduce function in Python

我正在尝试结合 Python 学习一些 mapreduce。

现在我有以下代码 运行 来自我正在做的教程。

from mrjob.job import MRJob

class SpendByCustomer(MRJob):

    def mapper(self, _, line):
        (customerID, itemID, orderAmount)  = line.split(',')
        yield customerID, float(orderAmount)

    def reducer(self, customerID, orders):
        yield customerID, sum(orders)


if __name__ == '__main__':
  SpendByCustomer.run()

它应该执行以下操作。

当我点击 !python SpendByCustomers.py customer-orders.xls > test.txt 它应该读入 .xls 文件,对其进行映射和缩减,然后将输出写入 test.txt.

一切正常,我基本明白了。不过,我真的很想获得更多关于以下内容的见解:

在Python中,字母、数字和下划线可以用于变量名。 (变量名不能 以数字开头 。)下划线是常用的变量名,表示不会使用的值。例如,如果我想打印 "hello" 5 次,我可以执行以下操作:

for _ in range(5):
    print("hello")

在那个例子中,_ 并没有真正做任何事情;它在那里是因为我们必须在那里放置一些变量名,但是使用 that 变量名是给其他查看代码的程序员的消息,即该变量将不会被使用。对于函数,这是因为通常使用三个参数调用 mapper 方法,但在您的 mapper 方法中,该参数未被使用。至于第二个问题,SpendByCustomer.run()mrjob.job.MRJob中定义的方法class。您可能已经从其名称中猜到,它运行 MapReduce 作业。它使用您的 mapper() 方法和 reducer() 方法来完成。

In

def mapper(self, _, line):

What is the _ doing here?

MRJob.mapper 具有方法签名 MRJob.mapper(key, value)

如果您在派生的 class 中重新定义它(就像您所做的那样),您必须保持兼容的签名,因此您必须接受两个参数。你的函数将被调用,一些键作为第一个参数,一些值作为第二个参数。文档指出 "if you don’t mess with Protocols" 你将被调用的密钥将是 None,所以它不是特别有趣。因此,您对该方法的重新定义不会对其执行任何操作。

在 Python 中,通常使用名称 _ 作为签名中必须具有的参数以保持与接口兼容。从技术上讲,这个参数名称没有什么特别之处。它只是使用标识符允许的字符之一的单字符名称。选择它主要是因为它的视觉外观(看起来有点像未填充的字段)告诉人类读者你的代码:我在这里传递了一个值,但我不关心它是什么(并且不会在我的实现)。

In

if __name__ == '__main__':
  SpendByCustomer.run()

What is this function exactly doing?

关于 if __name__ == '__main__': 部分,请参阅 What does if __name__ == "__main__": do?

.run()部分参考MRJob documentation.