MapReduce求平均值

一:背景

求平均数是MapReduce比较常见的算法,求平均数的算法也比较简单,一种思路是Map端读取数据,Reduce端汇总并且统计记录数,然后作商即可。

二:技术实现

#需求:现有成绩单如下,求出每个同学的平均成绩

[java] view plaincopy

  1. 小民  语文  80
  2. 小民  数学  98
  3. 小民  英语  89
  4. 小芳  语文  88
  5. 小芳  数学  99
  6. 小芳  英语  90

实现代码:

[java] view plaincopy

  1. public class AverageTest {
  2. // 定义输入路径
  3. private static final String INPUT_PATH = "hdfs://liaozhongmin:9000/average_file";
  4. // 定义输出路径
  5. private static final String OUT_PATH = "hdfs://liaozhongmin:9000/out";
  6. public static void main(String[] args) {
  7. try {
  8. // 创建配置信息
  9. Configuration conf = new Configuration();
  10. // 创建文件系统
  11. FileSystem fileSystem = FileSystem.get(new URI(OUT_PATH), conf);
  12. // 如果输出目录存在,我们就删除
  13. if (fileSystem.exists(new Path(OUT_PATH))) {
  14. fileSystem.delete(new Path(OUT_PATH), true);
  15. }
  16. // 创建任务
  17. Job job = new Job(conf, AverageTest.class.getName());
  18. //1.1   设置输入目录和设置输入数据格式化的类
  19. FileInputFormat.setInputPaths(job, INPUT_PATH);
  20. job.setInputFormatClass(TextInputFormat.class);
  21. //1.2   设置自定义Mapper类和设置map函数输出数据的key和value的类型
  22. job.setMapperClass(AverageMapper.class);
  23. job.setMapOutputKeyClass(Text.class);
  24. job.setMapOutputValueClass(Text.class);
  25. //1.3   设置分区和reduce数量(reduce的数量,和分区的数量对应,因为分区为一个,所以reduce的数量也是一个)
  26. job.setPartitionerClass(HashPartitioner.class);
  27. job.setNumReduceTasks(1);
  28. //1.4   排序
  29. //1.5   归约
  30. //2.1   Shuffle把数据从Map端拷贝到Reduce端。
  31. //2.2   指定Reducer类和输出key和value的类型
  32. job.setReducerClass(AverageReducer.class);
  33. job.setOutputKeyClass(Text.class);
  34. job.setOutputValueClass(FloatWritable.class);
  35. //2.3   指定输出的路径和设置输出的格式化类
  36. FileOutputFormat.setOutputPath(job, new Path(OUT_PATH));
  37. job.setOutputFormatClass(TextOutputFormat.class);
  38. // 提交作业 退出
  39. System.exit(job.waitForCompletion(true) ? 0 : 1);
  40. } catch (Exception e) {
  41. e.printStackTrace();
  42. }
  43. }
  44. public static class AverageMapper extends Mapper<LongWritable, Text, Text, Text>{
  45. //设置输出的key和value
  46. private Text outKey = new Text();
  47. private Text outValue = new Text();
  48. @Override
  49. protected void map(LongWritable key, Text value, Mapper<LongWritable, Text, Text, Text>.Context context) throws IOException, InterruptedException {
  50. //获取输入的行
  51. String line = value.toString();
  52. //取出无效记录
  53. if (line == null || line.equals("")){
  54. return ;
  55. }
  56. //对数据进行切分
  57. String[] splits = line.split("\t");
  58. //截取姓名和成绩
  59. String name = splits[0];
  60. String score = splits[2];
  61. //设置输出的Key和value
  62. outKey.set(name);
  63. outValue.set(score);
  64. //将结果写出去
  65. context.write(outKey, outValue);
  66. }
  67. }
  68. public static class AverageReducer extends Reducer<Text, Text, Text, FloatWritable>{
  69. //定义写出去的Key和value
  70. private Text name = new Text();
  71. private FloatWritable avg = new FloatWritable();
  72. @Override
  73. protected void reduce(Text key, Iterable<Text> value, Reducer<Text, Text, Text, FloatWritable>.Context context) throws IOException, InterruptedException {
  74. //定义科目数量
  75. int courseCount = 0;
  76. //定义中成绩
  77. int sum = 0;
  78. //定义平均分
  79. float average = 0;
  80. //遍历集合求总成绩
  81. for (Text val : value){
  82. sum += Integer.parseInt(val.toString());
  83. courseCount ++;
  84. }
  85. //求平均成绩
  86. average = sum / courseCount;
  87. //设置写出去的名字和成绩
  88. name.set(key);
  89. avg.set(average);
  90. //把结果写出去
  91. context.write(name, avg);
  92. }
  93. }
  94. }

程序运行的结果:

时间: 2024-10-12 02:10:31

MapReduce求平均值的相关文章

Hadoop阅读笔记(二)——利用MapReduce求平均数和去重

前言:圣诞节来了,我怎么能虚度光阴呢?!依稀记得,那一年,大家互赠贺卡,短短几行字,字字融化在心里:那一年,大家在水果市场,寻找那些最能代表自己心意的苹果香蕉梨,摸着冰冷的水果外皮,内心早已滚烫.这一年……我在博客园-_-#,希望用dt的代码燃烧脑细胞,温暖小心窝. 上篇<Hadoop阅读笔记(一)——强大的MapReduce>主要介绍了MapReduce的在大数据集上处理的优势以及运行机制,通过专利数据编写Demo加深了对于MapReduce中输入输出数据结构的细节理解.有了理论上的指导,仍

求平均值接口与实现该接口的类

求平均值接口与实现该接口的类,声明一个Average接口,其中约定求平均值的方法,声明多个类实现Average接口,分别给出求平均值的方法实现,例如,在第一组数值中,算法一 全部数值相加后求平均值,算法二,去掉一个最高分和一个最低分,再将总分求平均,算法三,求加权平均分的值. 1,在主函数中声明了三个类,第一个类实现全部算法相加后求平均值. 2,第二个类实现去掉一个最高分和一个最低分之后求平均值. 3.第三个类实现求加权平均分的值. 4,程序运行后产生的结果是32.75,9.25,6.75 5,

生成指定范围的一组随机数并求平均值

Math.random()是令系统随机选取大于等于 0.0 且小于 1.0 的伪随机 double 值,是Java语言常用代码. 随机数生成20~90之间的数值,并求平均数: public class Random01 { public static void main(String[] args) { int len = 5; int sum = 0; int[] arr = new int[len]; for (int i = 0; i < len; i++) { arr[i] = (int

1140: 零起点学算法47——求平均值

1140: 零起点学算法47--求平均值 Time Limit: 1 Sec  Memory Limit: 64 MB   64bit IO Format: %lldSubmitted: 1408  Accepted: 873[Submit][Status][Web Board] Description 输入一些整数,求平均值 Input 多组测试数据 首先输入1个整数n表示测试组数 然后每行首先输入1个整数m,再输入m个整数 Output 对于每组测试数据输出1行,内容为m个整数的平均值,保留

1054. 求平均值 (20)-PAT乙级真题

今天刚刚到学校,2017年学习正式开始了,今天看到了浙大的<数据结构>这学期又要开课了,决定一定要跟着学习一遍:在大学生mooc网上学习:http://www.icourse163.org/course/zju-93001#/info :然后就是跟着<算法之美>也要同步看完. 然后就在PAT上随便做一道题,这是第一次通过AC,发现了两个比较好的博客主页:http://www.liuchuo.net/  和  https://www.joyhwong.com/   都总结了刷题的过程

1054. 求平均值 (20)(转载)

1054. 求平均值 (20) 本题的基本要求非常简单:给定N个实数,计算它们的平均值.但复杂的是有些输入数据可能是非法的.一个"合法"的输入是[-1000,1000]区间内的实数,并且最多精确到小数点后2位.当你计算平均值的时候,不能把那些非法的数据算在内. 输入格式: 输入第一行给出正整数N(<=100).随后一行给出N个实数,数字间以一个空格分隔. 输出格式: 对每个非法输入,在一行中输出"ERROR: X is not a legal number",

偶数分割求平均值

////////////有一个长度为n(n<=100)的数列,该数列定义为//从2开始的递增有序偶数,现在要求你按照顺序每m个//数求出一个平均值,如果最后不足m个,//则以实际数量求平均值.编程输出该平均值序列. #include<stdio.h> int a[101]; void main() { int n,m; int i,sum; for(i=1;i<=100;i++) a[i]=2*i; while(scanf("%d%d",&n,&

C语言之基本算法08—去掉最高分去掉最低分求平均值

// /* ================================================================== 题目:选拔赛中通常用这样的办法求选手分数,去掉一个最高分,去掉一个 最低分,求平均成绩!请编程实现这个计算方法. ================================================================== */ #include<stdio.h> main() { float a[10],max,min,su

1114: 零起点学算法21——求平均值

1114: 零起点学算法21--求平均值 Time Limit: 1 Sec  Memory Limit: 64 MB   64bit IO Format: %lldSubmitted: 4420  Accepted: 1634[Submit][Status][Web Board] Description 输入3个浮点数,求出平均值,保留3位小数 Input 输入3个浮点数数(多组数据) Output 输出平均值,保留3位小数(每组数据一行) Sample Input 2 3 4 Sample