MapReduce--10--学生成绩(基础版)--需求1

对于刚入门MapReduce的同学来说,学会mapreduce的基本编程套路,懂得mapreduce是如何对于大批量数据集做分布式运算的是非常关键的。

这里有一个需求,增强各位对mapreduce编程的理解

首先看数据:

computer,huangxiaoming,85
computer,xuzheng,54
computer,huangbo,86
computer,liutao,85
computer,huanglei,99
computer,liujialing,85
computer,liuyifei,75
computer,huangdatou,48
computer,huangjiaju,88
computer,huangzitao,85
english,zhaobenshan,57
english,liuyifei,85
english,liuyifei,76
english,huangdatou,48
english,zhouqi,85
english,huangbo,85
english,huangxiaoming,96
english,huanglei,85
english,liujialing,75
algorithm,liuyifei,75
algorithm,huanglei,76
algorithm,huangjiaju,85
algorithm,liutao,85
algorithm,huangdou,42
algorithm,huangzitao,81
math,wangbaoqiang,85
math,huanglei,76
math,huangjiaju,85
math,liutao,48
math,xuzheng,54
math,huangxiaoming,85
math,liujialing,85

以上所有的是数据,该数据每行有三个字段值,分别是course,name,score

现在求:需求1:每一个course的最高分,最低分,平均分


返回结果格式:
course    95    22    55
例子:
computer    99    48    75

 

解题思路:

对于要求每门课程的最高分,最低分,平均分,这其实就是简单的按照课程分组,然后对分数做max,min,avg的聚合操作。

对于需求来说,并不复杂

对于mapper阶段,输出的key-value分别是:

key: 课程 course

value: 分数 score

对于reducer阶段,reduce方法接收的参数是:

key: 课程 course

values: 某一门课程对应的所有的score的一个迭代器

对于任何一个MapReduce程序来说,清楚的知道mapper阶段和reducer阶段的输入和输出是什么,这是写出mapreduce程序的关键

 

具体看代码实现:

package com.ghgj.mazh.mapreduce.exercise.coursescore2;

import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.LongWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Job;
import org.apache.hadoop.mapreduce.Mapper;
import org.apache.hadoop.mapreduce.Reducer;
import org.apache.hadoop.mapreduce.lib.input.FileInputFormat;
import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

public class CourseScoreMR_Basic_01 {

    public static void main(String[] args) throws Exception {
        /**
         * 一些参数的初始化
         */
        String inputPath = "D:\\bigdata\\coursescore1\\input";
        String outputPath = "D:\\bigdata\\coursescore1\\output";

        /**
         * 初始化一个Job对象
         */
        Configuration conf = new Configuration();
        Job job = Job.getInstance(conf);

        /**
         * 设置jar包所在路径
         */
        job.setJarByClass(CourseScoreMR_Basic_01.class);

        /**
         * 指定mapper类和reducer类 等各种其他业务逻辑组件
         */
        job.setMapperClass(Mapper_CS.class);
        job.setReducerClass(Reducer_CS.class);
        // 指定maptask的输出类型
        job.setMapOutputKeyClass(Text.class);
        job.setMapOutputValueClass(Text.class);
        // 指定reducetask的输出类型
        job.setOutputKeyClass(Text.class);
        job.setOutputValueClass(Text.class);

        /**
         * 指定该mapreduce程序数据的输入和输出路径
         */
        Path input = new Path(inputPath);
        Path output = new Path(outputPath);
        FileSystem fs = FileSystem.get(conf);
        if (fs.exists(output)) {
            fs.delete(output, true);
        }
        FileInputFormat.setInputPaths(job, input);
        FileOutputFormat.setOutputPath(job, output);

        /**
         * 最后提交任务
         */
        boolean waitForCompletion = job.waitForCompletion(true);
        System.exit(waitForCompletion ? 0 : 1);
    }

    /**
     * Mapper组件:
     * <p>
     * 输入的key:
     * 输入的value: computer,huangxiaoming,85
     * <p>
     * 输出的key: couse
     * 输入的value: score
     */
    private static class Mapper_CS extends Mapper<LongWritable, Text, Text, Text> {

        Text keyOut = new Text();
        Text valueOut = new Text();

        @Override
        protected void map(LongWritable key, Text value, Context context) throws IOException, InterruptedException {

            String[] splits = value.toString().split(",");
            String course = splits[0];
            String score = splits[2];

            keyOut.set(course);
            valueOut.set(score);

            context.write(keyOut, valueOut);
        }
    }

    /**
     * Reducer组件:
     * <p>
     * 输入的key:
     * 输入的values:
     * <p>
     * 输出的key:
     * 输入的value:
     */
    private static class Reducer_CS extends Reducer<Text, Text, Text, Text> {

        Text valueOut = new Text();

        List<Integer> scoreList = new ArrayList<>();

        @Override
        protected void reduce(Text key, Iterable<Text> values, Context context) throws IOException, InterruptedException {

            scoreList.clear();
            for(Text t: values){
                scoreList.add(Integer.valueOf(t.toString()));
            }

            // 求最高成绩和最低成绩
            Integer maxScore = Collections.max(scoreList);
            Integer minScore = Collections.min(scoreList);

            int sumScore = 0;
            for(int score: scoreList){
                sumScore += score;
            }

            // 求平均成绩
            double avgScore = sumScore *1D / scoreList.size();

            valueOut.set(maxScore + "\t" + minScore + "\t" + Math.round(avgScore));
            context.write(key, valueOut);
        }
    }
}

 

最后的执行结果:

algorithm	85	42	74
computer	99	48	79
english	    96	48	77
math	    85	48	74

 

第一个需求偏简单,就相当于是练习简单的求解max, min, avg的操作

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值