在 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
.
一切正常,我基本明白了。不过,我真的很想获得更多关于以下内容的见解:
在
def mapper(self, _, line):
_
在这里做什么?
在
if __name__ == '__main__':
SpendByCustomer.run()
这个函数到底在做什么?
在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.
我正在尝试结合 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
.
一切正常,我基本明白了。不过,我真的很想获得更多关于以下内容的见解:
在
def mapper(self, _, line):
_
在这里做什么?在
if __name__ == '__main__': SpendByCustomer.run()
这个函数到底在做什么?
在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.