我是一个初学者,刚刚开始使用mrjob库用python编写mapreduce程序。
视频教程中给出的一个例子是通过位置id查找最高温度,接下来编写另一个程序通过位置id查找最低温度也很简单。
我想知道,有没有一种方法可以在一个mapreduce程序中通过位置id同时产生最高和最低温度?。下面是我的做法:
from mrjob.job import MRJob
'''Sample Data
ITE00100554,18000101,TMAX,-75,,,E,
ITE00100554,18000101,TMIN,-148,,,E,
GM000010962,18000101,PRCP,0,,,E,
EZE00100082,18000101,TMAX,-86,,,E,
EZE00100082,18000101,TMIN,-135,,,E,
ITE00100554,18000102,TMAX,-60,,I,E,
ITE00100554,18000102,TMIN,-125,,,E,
GM000010962,18000102,PRCP,0,,,E,
EZE00100082,18000102,TMAX,-44,,,E,
Output I am expecting to see:
ITE00100554 32.3 20.2
EZE00100082 34.4 19.6
'''
class MaxMinTemperature(MRJob):
def mapper(self, _, line):
location, datetime, measure, temperature, w, x, y, z = line.split(',')
temperature = float(temperature)/10
if measure == 'TMAX' or measure == 'TMIN':
yield location, temperature
def reducer(self, location, temperatures):
yield location, max(temperatures), min(temperatures)
if __name__ == '__main__':
MaxMinTemperature.run()
我得到以下错误:
File "MaxMinTemperature.py", line 12, in reducer
yield location, max(temperatures), min(temperatures)
ValueError: min() arg is an empty sequence
这可能吗?
谢谢你的帮助。
希夫
2条答案
按热度按时间m528fe3b1#
减速器有两个问题:
若您检查温度参数的类型,您将看到它是一个生成器。一个生成器只能遍历一次,因此不能将同一个生成器同时传递给“min”和“max”函数。正确的解决方案是手动遍历它。错误的解决方案(将其转换为列表)可能会导致足够大的输入出现内存不足错误,因为列表将其所有元素都保存在内存中,而生成器没有。
reducer的结果必须是两个元素的元组。所以你需要在另一个元组中组合你的最低和最高温度。
完整的工作方案:
4si2a6ki2#
问题是
temperatures
在你的reducer
方法是生成器。为了更好地理解,让我们创建一个简单的生成器并查看其行为:
о此类对象的一个特点是,一旦耗尽,就不能重用它:
因此顺序执行
max()
以及min()
导致错误:所以,不能同时使用同一个生成器
max()
以及min()
内置函数,因为在第二次使用时,生成器将耗尽。相反,您可以:
1) 将生成器转换为列表并使用它:
2) 或提取1 for loop中生成器的最小值和最大值:
下面的编辑
reducer
:应该会修正错误。