MapReduce编程实例(一)-求平均数

开始学习写一些MR编程实例,工作中即将使用(刚刚开始,如果有错误和建议,欢迎指出)


现在有一个文件,里面记录了全校所有学生各科成绩,求每个学生的平均成绩,格式如下

小明 语文  92
小明 数学 88
小明 英语 90
小强 语文 76
小强 数学 66
小强 英语 80
小木 语文 60
小木 数学 65
小木 英语 61

解决思路

Map阶段先将数据拆成key:姓名,value:课程_成绩的格式提供给reduce,默认的partitioner会将名字相同的学生发到同一个reduce上面

这样reduce可以根据总分/科目数计算平均成绩。

逻辑比较简单,

代码如下:

[java]  view plain copy print ? 在CODE上查看代码片 派生到我的代码片
  1. package com.test.mr2;  
  2.   
  3. import java.io.IOException;  
  4. import java.util.Iterator;  
  5. import java.util.StringTokenizer;  
  6.   
  7. import org.apache.hadoop.conf.Configuration;  
  8. import org.apache.hadoop.fs.Path;  
  9. import org.apache.hadoop.io.FloatWritable;  
  10. import org.apache.hadoop.io.Text;  
  11. import org.apache.hadoop.mapreduce.Job;  
  12. import org.apache.hadoop.mapreduce.Mapper;  
  13. import org.apache.hadoop.mapreduce.Reducer;  
  14. import org.apache.hadoop.mapreduce.Reducer.Context;  
  15. import org.apache.hadoop.mapreduce.lib.input.FileInputFormat;  
  16. import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat;  
  17. import org.apache.hadoop.util.GenericOptionsParser;  
  18.   
  19. /* 
  20.  * 计算学生课程平均成绩(某学生总分/课程数) 
  21.  * 输入格式 
  22.  *  
  23.  * 小明   语文  92 
  24.  * 小明   数学  88 
  25.  * 小明   英语  90 
  26.  * 小强   语文  76 
  27.  * 小强   数学  66 
  28.  * 小强   英语  80 
  29.  * 小木   语文  60 
  30.  * 小木   数学  65 
  31.  * 小木   英语  61 
  32.  *  
  33.  * 输出 
  34.  *  
  35.  * 小明   90 
  36.  * 小强   74 
  37.  * 小木   62 
  38.  */  
  39. public class Average {  
  40.   
  41.     public static class AverMapper extends Mapper<Object, Text, Text, Text> {  
  42.         @Override  
  43.         protected void map(Object key, Text value, Context context)  
  44.                 throws IOException, InterruptedException {  
  45.             String line = value.toString();  
  46.             StringTokenizer stringTokenizer = new StringTokenizer(line, "\n");  
  47.             String name = "";  
  48.             StringBuffer out = new StringBuffer(32);  
  49.             while (stringTokenizer.hasMoreElements()) {  
  50.                 String tmp = stringTokenizer.nextToken();  
  51.                 StringTokenizer st = new StringTokenizer(tmp);  
  52.                 while (st.hasMoreElements()) {  
  53.                     name = st.nextToken();  
  54.                     out.append(st.nextToken());  
  55.                     out.append("_");  
  56.                     out.append(st.nextToken());  
  57.                     // 使用默认的hash partitioner将名字相同的同学发到一个reduce上  
  58.                     context.write(new Text(name), new Text(out.toString()));  
  59.                 }  
  60.             }  
  61.         }  
  62.   
  63.     }  
  64.   
  65.     public static class AverReducer extends  
  66.             Reducer<Text, Text, Text, FloatWritable> {  
  67.         @Override  
  68.         protected void reduce(Text key, Iterable<Text> values, Context context)  
  69.                 throws IOException, InterruptedException {  
  70.             Iterator<Text> it = values.iterator();  
  71.             //计算每个key对应的记录条数和总分数  
  72.             int count = 0;  
  73.             int sum = 0;  
  74.             while (it.hasNext()) {  
  75.                 String value = it.next().toString();  
  76.                 String[] strs = value.split("\\_");  
  77.                 if (strs.length < 2) {  
  78.                     continue;  
  79.                 }  
  80.                 try {  
  81.                     sum += Integer.parseInt(strs[1]);  
  82.                 } catch (Exception e) {  
  83.                     System.err.println(e.getMessage());  
  84.                 }  
  85.                 count++;  
  86.             }  
  87.             FloatWritable average = new FloatWritable(sum / count);  
  88.             context.write(key, average);  
  89.         }  
  90.     }  
  91.   
  92.     public static void main(String[] args) throws IOException, InterruptedException, ClassNotFoundException {  
  93.         System.out.println("Begin.....");  
  94.         Configuration conf =new Configuration();  
  95.         String[] arguments=new GenericOptionsParser(conf, args).getRemainingArgs();  
  96.         if(arguments.length<2){  
  97.             System.out.println("Usage:com.test.mr2.Average in out");  
  98.             System.exit(1);  
  99.         }  
  100.         Job job=new Job(conf,"Average");  
  101.         job.setJarByClass(Average.class);  
  102.         job.setMapperClass(AverMapper.class);  
  103.         job.setReducerClass(AverReducer.class);  
  104.         job.setMapOutputValueClass(Text.class);  
  105.         job.setMapOutputKeyClass(Text.class);  
  106.         job.setOutputKeyClass(Text.class);  
  107.         job.setOutputValueClass(FloatWritable.class);  
  108.         FileInputFormat.addInputPath(job, new Path(arguments[0]));  
  109.         FileOutputFormat.setOutputPath(job, new Path(arguments[1]));  
  110.         System.exit(job.waitForCompletion(true)?0:1);  
  111.         System.out.println("End.....");  
  112.     }  
  113.   
  114. }  
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值