我正在尝试制作一个映射器/还原器程序,从数据集计算最大/最小温度。我试着自己修改,但代码不起作用。映射器运行良好,但reducer不运行,因为我在映射器中进行了更改。
我的示例代码:mapper.py
import re
import sys
for line in sys.stdin:
val = line.strip()
(year, temp, q) = (val[14:18], val[25:30], val[31:32])
if (temp != "9999" and re.match("[01459]", q)):
print "%st%s" % (year, temp)
还原剂.py
import sys
(last_key, max_val) = (None, -sys.maxint)
for line in sys.stdin:
(key, val) = line.strip().split("t")
if last_key and last_key != key:
print "%st%s" % (last_key, max_val)
(last_key, max_val) = (key, int(val))
else:
(last_key, max_val) = (key, max(max_val, int(val)))
if last_key:
print "%st%s" % (last_key, max_val)
文件中的示例行:
69019013910,2012**0101,*42.9,18,29.4,18,1033.3,18,968.7,18,10.0,18,8.7,18、15.0,999.9,52.5,31.6*,0.00I,999.9000000,
我需要粗体的值。任何想法!!
如果我将mapper作为一个简单的代码运行,这就是我的输出:
root@ubuntu:/home/hduser/files# python maxtemp-map.py
2012 42.9
2012 50.0
2012 47.0
2012 52.0
2012 43.4
2012 52.6
2012 51.1
2012 50.9
2012 57.8
2012 50.7
2012 44.6
2012 46.7
2012 52.1
2012 48.4
2012 47.1
2012 51.8
2012 50.6
2012 53.4
2012 62.9
2012 62.6
该文件包含不同年份的数据。我必须计算每一年的最小值、最大值和平均值。
FIELD POSITION TYPE DESCRIPTION
STN--- 1-6 Int. Station number (WMO/DATSAV3 number)
for the location.
WBAN 8-12 Int. WBAN number where applicable--this is the
historical
YEAR 15-18 Int. The year.
MODA 19-22 Int. The month and day.
TEMP 25-30 Real Mean temperature. Missing = 9999.9
Count 32-33 Int. Number of observations in mean temperature
我在解析你的问题时遇到了问题,但我认为它可以简化为:
您有一个数据集,数据集的每一行代表与单个时间点相关的不同数量。您希望从整个数据集中提取其中一个量的最大值/最小值。
如果是这样的话,我会这样做:
temps = []
with open(file_name, 'r') as infile:
for line in infile:
line = line.strip().split(',')
year = int(line[2][:4])
temp = int(line[3])
temps.append((temp, year))
temps = sorted(temps)
min_temp, min_year = temps[0]
max_temp, max_year = temps[-1]
编辑:
法利,我认为你用mapper/reducer做的事情可能对你想要从数据中得到的东西来说有些过头了。以下是一些关于初始文件结构的附加问题。
- 数据集中每一行的内容(具体而言)是什么?例如:
date, time, temp, pressure, ...
- 您希望从每一行中提取哪一段数据?温度那条数据在这行的哪个位置
- 每个文件是否只包含一年的数据
例如,如果您的数据集看起来像
year, month, day, temp, pressure, cloud_coverage, ...
year, month, day, temp, pressure, cloud_coverage, ...
year, month, day, temp, pressure, cloud_coverage, ...
year, month, day, temp, pressure, cloud_coverage, ...
year, month, day, temp, pressure, cloud_coverage, ...
year, month, day, temp, pressure, cloud_coverage, ...
那么最简单的方法就是遍历每一行并提取相关信息。看来你只想要年份和温度。在该示例中,它们位于每行中的位置0
和3
。因此,我们将有一个看起来像的循环
from collections import defaultdict
data = defaultdict(list)
with open(file_name, 'r') as infile:
for line in infile:
line = line.strip().split(', ')
year = line[0]
temp = line[3]
data[year].append(temp)
请看,我们从文件中的每一行提取了year
和temp
,并将它们存储在一个特殊的dictionary对象中。如果我们把它打印出来,它会是什么样子
year1: [temp1, temp2, temp3, temp4]
year2: [temp5, temp6, temp7, temp8]
year3: [temp9, temp10, temp11, temp12]
year4: [temp13, temp14, temp15, temp16]
现在,这使得我们可以非常方便地统计某一年的所有温度。例如,为了计算最大、最小和平均温度,我们可以进行
import numpy as np
for year in data:
temps = np.array( data[year] )
output = (year, temps.mean(), temps.min(), temps.max())
print 'Year: {0} Avg: {1} Min: {2} Max: {3}'.format(output)
我非常愿意帮助你解决问题,但我需要你更具体地说明你的数据到底是什么样子的,以及你想提取什么。
如果您有类似商店名称和商店总销售额的东西作为映射器的中间结果,您可以使用以下内容作为减少器来找出最大销售额以及哪个商店的销售额最大。同样,它会找出最低销售额以及哪家商店的销售额最低。
下面的reducer代码示例假设您将每个商店的销售总额作为输入文件。
#! /usr/bin/python
import sys
mydict = {}
salesTotal = 0
oldKey = None
for line in sys.stdin:
data=line.strip().split("t")
if len(data)!=2:
continue
thisKey, thisSale = data
if oldKey and oldKey != thisKey:
mydict[oldKey] = float(salesTotal)
salesTotal = 0
oldKey = thisKey
salesTotal += float(thisSale)
if oldKey!= None:
mydict[oldKey] = float(salesTotal)
maximum = max(mydict, key=mydict.get)
print(maximum, mydict[maximum])
minimum = min(mydict, key=mydict.get)
print(minimum, mydict[minimum])