试图从文本文件显示城市的最高温度,但我有所有的城市和温度

时间:2015-04-16 10:13:06

标签: python hadoop mapreduce

我正在尝试开发一个mapreduce程序,以便从文本文件中显示最高温度的城市。

文本文件“Temperats.txt”包含此内容(城市和温度):

City1 10

City2 11

City3 4

City4 20

...

city10000 22

在这个例子中,我想要的结果是打印最后一行,它具有更高的温度:

city10000 22

我有这样的reducer文件:

import sys

current_city = None
current_max = 0
city = None

for line in sys.stdin:
    line = line.strip()

    city, temperature = line.rsplit('\t', 1)

    try:
        temperature = float(temperature)
    except ValueError:
        continue

    if current_city == city:
        if temperature > current_max:
            current_max = temperature
    else:
        if current_city:
            print '%s\t%s' % (current_city, current_max)
        current_max = temperature
        current_city = city

if current_city == city:
    print '%s\t%s' % (current_city, current_max)

但是,当我测试这个reducer.py文件时,我总是得到相同的结果,我总是得到所有的城市和温度,如下:

City1 10

City2 11

City3 4

City4 20

...

city10000 22

你的reducer文件中有什么问题吗?

我只是想显示最高温度的城市,在这种情况下,最高温度的城市是city10000,所以我只想要这个结果:

city10000 22

3 个答案:

答案 0 :(得分:2)

首先让我解释一下我认为代码出错的地方然后我会提供一个有效的例子。问题在于reducer中的if else语句。

以下是if部分:

if current_city == city:
    if temperature > current_max:
        current_max = temperature

只有当同一个城市列出两次时才会发生这种情况,更多重要这是代码检查新城市temperature是否大于{{}的唯一地方1}}。

我怀疑大部分时间都花在声明的current_max部分:

else

这里有两个问题:

  1. 定义else: if current_city: print '%s\t%s' % (current_city, current_max) current_max = temperature current_city = city 时,程序将始终打印一行。这就是从reducer中生成城市列表的原因。

  2. 该程序还会协助current_city变量,而不检查current_max是否更大。

  3. 这是一个应该有效的减速器:

    temperature

    我要提到的最后一件事是设置import sys current_city = None current_max = 0 city = None for line in sys.stdin: line = line.strip() city, temperature = line.rsplit('\t', 1) try: temperature = float(temperature) except ValueError: continue if temperature > current_max: current_max = temperature current_city = city print '%s\t%s' % (current_city, current_max) 不是一个好主意。摄氏温度很容易低于零。如果您的城市和温度列表是在冬季,那么它们可能没有温度超过0且代码会返回:

    current_max = 0

答案 1 :(得分:1)

我对python一无所知。但您可以遵循以下方案:

- >创建一个地图,将密钥存储为城市,将值存储为温度。

- >现在,将前五个城市的温度存储在地图上。

- >在5个城市之后,将每个城市的温度与地图中的所有5个城市进行比较。如果地图中任何城市的温度较低,则用新城市替换该城市及其温度。

- >最后,您可以打印地图。这将使5个城市的温度达到最高。

答案 2 :(得分:1)

import java.io.IOException;
import java.util.*;
import java.util.Map.Entry;

 import org.apache.hadoop.fs.Path;
import org.apache.hadoop.conf.*;
import org.apache.hadoop.io.*;
import org.apache.hadoop.mapreduce.*;
import org.apache.hadoop.mapreduce.lib.input.FileInputFormat;
import org.apache.hadoop.mapreduce.lib.input.TextInputFormat;
import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat;
import org.apache.hadoop.mapreduce.lib.output.TextOutputFormat;

 public class Weather {

  public static class Map extends Mapper<LongWritable, Text, Text, IntWritable> {

     public void map(LongWritable key, Text value, Context context) throws IOException, InterruptedException {
         String line = value.toString();
           String year = line.substring(15, 19);

           int airTemperature;
           if (line.charAt(87) == '+') {
                        airTemperature= Integer.parseInt(line.substring(88, 92));
                    }
           else
               airTemperature= - Integer.parseInt(line.substring(88, 92));

                if(airTemperature!=9999 && airTemperature!=-9999){
                    airTemperature/=10;
                context.write(new Text(year),new IntWritable(airTemperature));
                }
       }
  } 

  public static class Reduce extends Reducer<Text, IntWritable, Text, IntWritable> {

     public void reduce(Text key, Iterable<IntWritable> values, Context context) 
       throws IOException, InterruptedException {

         int maxValue=Integer.MIN_VALUE;

         Iterator<IntWritable> itr = values.iterator();
         while(itr.hasNext()){
             maxValue = Math.max(maxValue,itr.next().get());
         }
         context.write(key, new IntWritable(maxValue));
     }
  }

  public static void main(String[] args) throws Exception {
     Configuration conf = new Configuration();

         Job job = new Job(conf, "temparature");
     job.setOutputKeyClass(Text.class);
     job.setOutputValueClass(IntWritable.class);

     job.setMapperClass(Map.class);
     job.setReducerClass(Reduce.class);
     job.setCombinerClass(Reduce.class);  

     job.setMapOutputKeyClass(Text.class);
     job.setMapOutputValueClass(IntWritable.class);

     job.setInputFormatClass(TextInputFormat.class);
     job.setOutputFormatClass(TextOutputFormat.class);

     FileInputFormat.addInputPath(job, new Path("hdfs://localhost:8020/input/"));
     FileOutputFormat.setOutputPath(job, new Path("hdfs://localhost:8020/output/"));

     // FileInputFormat.addInputPath(job, new Path(args[0]));
    //  FileOutputFormat.setOutputPath(job, new Path(args[1]));

     job.waitForCompletion(true);
  }

 }

天气数据数据集:

0029029070999991901010106004 + 64333 + 023450FM-12 + + 000599999V0202701N015919999999N0000001N9-00781 99999102001ADDGF108991999999999999999999