MapReduce最佳成绩统计,男生女生比比看

上一篇文章我们了解了MapReduce优化方面的知识,现在我们通过简单的项目,学会如何优化MapReduce性能

1、项目介绍

我们使用简单的成绩数据集,统计出0~20、20~50、50~100这三个年龄段的男、女学生的最高分数

2、数据集

姓名     年龄  性别   成绩

Alice     23   female  45

Bob      34   male   89

Chris    67   male   97

Kristine   38   female  53

Connor    25   male   27

Daniel    78   male   95

James    34   male   79

Alex      52  male   69

3、分析

基于需求,我们通过以下几步完成:

1、编写Mapper类,按需求将数据集解析为key=gender,value=name+age+score,然后输出

2、编写Partitioner类,按年龄段,将结果指定给不同的Reduce执行

3、编写Reducer类,分别统计出男女学生的最高分

4、编写run方法执行MapReduce作业

4、实现

package com.buaa;
import java.io.IOException;

import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.conf.Configured;
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.Partitioner;
import org.apache.hadoop.mapreduce.Reducer;
import org.apache.hadoop.mapreduce.lib.input.FileInputFormat;
import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat;
import org.apache.hadoop.util.Tool;
import org.apache.hadoop.util.ToolRunner;

/**
* @ProjectName BestScoreCount
* @PackageName com.buaa
* @ClassName Gender
* @Description 统计不同年龄段内,男、女最高分数
* @Author 刘吉超
* @Date 2016-05-09 09:49:50
*/
public class Gender extends Configured implements Tool {
    private static String TAB_SEPARATOR = "\t"; 

    public static class GenderMapper extends Mapper<LongWritable, Text, Text, Text> {
        /*
         * 调用map解析一行数据,该行的数据存储在value参数中,然后根据\t分隔符,解析出姓名,年龄,性别和成绩
         */
        public void map(LongWritable key, Text value, Context context) throws IOException, InterruptedException {
            /*
             * 姓名            年龄        性别        成绩
             * Alice           23         female     45
             * 每个字段的分隔符是tab键
             */
            // 使用\t,分割数据
            String[] tokens = value.toString().split(TAB_SEPARATOR);

            // 性别
            String gender = tokens[2];
            // 姓名    年龄    成绩
            String nameAgeScore = tokens[0] + TAB_SEPARATOR + tokens[1] + TAB_SEPARATOR + tokens[3];

            // 输出  key=gender  value=name+age+score
            context.write(new Text(gender), new Text(nameAgeScore));
        }
    }

    /*
     * 合并 Mapper输出结果
     */
    public static class GenderCombiner extends Reducer<Text, Text, Text, Text>  {

        public void reduce(Text key, Iterable<Text> values, Context context)throws IOException, InterruptedException {
            int maxScore = Integer.MIN_VALUE;
            int score = 0;
            String name = " ";
            String age = " ";

            for (Text val : values) {
                String[] valTokens = val.toString().split(TAB_SEPARATOR);
                score = Integer.parseInt(valTokens[2]);
                if (score > maxScore) {
                    name = valTokens[0];
                    age = valTokens[1];
                    maxScore = score;
                }
            }

            context.write(key, new Text(name + TAB_SEPARATOR + age + TAB_SEPARATOR + maxScore));
        }
    }

    /*
     * 根据 age年龄段将map输出结果均匀分布在reduce上
     */
    public static class GenderPartitioner extends Partitioner<Text, Text> {

        @Override
        public int getPartition(Text key, Text value, int numReduceTasks) {
            String[] nameAgeScore = value.toString().split(TAB_SEPARATOR);
            // 学生年龄
            int age = Integer.parseInt(nameAgeScore[1]);

            // 默认指定分区 0
            if (numReduceTasks == 0)
                return 0;

            // 年龄小于等于20,指定分区0
            if (age <= 20) {
                return 0;
            }else if (age <= 50) { // 年龄大于20,小于等于50,指定分区1
                return 1 % numReduceTasks;
            }else // 剩余年龄,指定分区2
                return 2 % numReduceTasks;
        }
    }

    /*
     * 统计出不同性别的最高分
     */
    public static class GenderReducer extends Reducer<Text, Text, Text, Text>  {
        @Override
        public void reduce(Text key, Iterable<Text> values, Context context) throws IOException, InterruptedException {
            int maxScore = Integer.MIN_VALUE;
            int score = 0;
            String name = " ";
            String age = " ";
            String gender = " ";

            // 根据key,迭代 values集合,求出最高分
            for (Text val : values) {
                String[] valTokens = val.toString().split(TAB_SEPARATOR);
                score = Integer.parseInt(valTokens[2]);
                if (score > maxScore) {
                    name = valTokens[0];
                    age = valTokens[1];
                    gender = key.toString();
                    maxScore = score;
                }
            }

            context.write(new Text(name), new Text("age:" + age + TAB_SEPARATOR + "gender:" + gender + TAB_SEPARATOR + "score:" + maxScore));
        }
    }

    @SuppressWarnings("deprecation")
    @Override
    public int run(String[] args) throws Exception {
        // 读取配置文件
        Configuration conf = new Configuration();

        Path mypath = new Path(args[1]);
        FileSystem hdfs = mypath.getFileSystem(conf);
        if (hdfs.isDirectory(mypath)) {
            hdfs.delete(mypath, true);
        }

        // 新建一个任务
        Job job = new Job(conf, "gender");
        // 主类
        job.setJarByClass(Gender.class);
        // Mapper
        job.setMapperClass(GenderMapper.class);
        // Reducer
        job.setReducerClass(GenderReducer.class);

        // map 输出key类型
        job.setMapOutputKeyClass(Text.class);
        // map 输出value类型
        job.setMapOutputValueClass(Text.class);

        // reduce 输出key类型
        job.setOutputKeyClass(Text.class);
        // reduce 输出value类型
        job.setOutputValueClass(Text.class);

        // 设置Combiner类
        job.setCombinerClass(GenderCombiner.class);

        // 设置Partitioner类
        job.setPartitionerClass(GenderPartitioner.class);
        // reduce个数设置为3
        job.setNumReduceTasks(3);

        // 输入路径
        FileInputFormat.addInputPath(job, new Path(args[0]));
        // 输出路径
        FileOutputFormat.setOutputPath(job, new Path(args[1]));

        // 提交任务
        return job.waitForCompletion(true)?0:1;
    }

    public static void main(String[] args) throws Exception {
        String[] args0 = {
                "hdfs://ljc:9000/buaa/gender/gender.txt",
                "hdfs://ljc:9000/buaa/gender/out/"
        };
        int ec = ToolRunner.run(new Configuration(),new Gender(), args0);
        System.exit(ec);
    }
}

5、运行效果

如果,您认为阅读这篇博客让您有些收获,不妨点击一下右下角的【推荐】。
如果,您希望更容易地发现我的新博客,不妨点击一下左下角的【关注我】。
如果,您对我的博客所讲述的内容有兴趣,请继续关注我的后续博客,我是【刘超★ljc】。

本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

实现代码及数据:下载

时间: 2024-08-30 06:25:14

MapReduce最佳成绩统计,男生女生比比看的相关文章

实训任务05 MapReduce获取成绩表的最高分记录

实训任务05  MapReduce获取成绩表的最高分记录 实训1:统计用户纺问次数 任务描述: 统计用户在2016年度每个自然日的总访问次数.原始数据文件中提供了用户名称与访问日期.这个任务就是要获取以每个自然日为单位的所有用户访问次数的累加值.如果通过MapReduce编程实现这个任务,首先要考虑的是,Mapper与Reducer各自的处理逻辑是怎样的:然后根据处理逻辑编写出核心代码:最后在Eclipse中编写完整代码,编译打包后提交给集群运行. 分析思路和逻辑 (1)       输入/输出

FOJ_Problem 1587 成绩统计

水题,不过要想0ms过还是有个技巧的: #include <iostream> #include <cstring> using namespace std; int main() { int score[101]; int t,t1,temp; while(cin>>t) { //memset(score,0,sizeof(score));这样时效性不高了,因为memset()是按字节处理数据的,并且有个函数调用的过程 for (int i=0;i<101;i+

sdut 3-5 学生成绩统计

3-5 学生成绩统计 Time Limit: 1000MS Memory limit: 65536K 题目描述 通过本题目练习可以掌握对象数组的用法,主要是对象数组中数据的输入输出操作. 设计一个学生类Student它具有私有的数据成员:学号.姓名.数学成绩.英语成绩.计算机成绩:具有公有的成员函数:求三门课总成绩的函数int sum();求三门课平均成绩的函数double average();输出学生基本信息.总成绩和平均成绩的函数void print():设置学生数据信息的函数voidset

????OJ平台:数组成绩统计

复仇者联盟之数组成绩统计 Description 定义一个5行3列的二维数组,各行分别代表一名学生的高数.英语.C++成绩.再定义一个有5个元素的一维数组,用于存储每名学生的平均成绩.请输入学生的各门课成绩,输出带平均成绩的成绩单,以及所有学生平均成绩的平均值. Input 15个整数,表示5名学生3科的成绩 Output 分5行显示每名学生的成绩及平均成绩 再显示所有学生平均成绩的平均值(保留两位小数) Sample Input 97 78 87 78 63 68 73 81 85 91 87

体育成绩统计——20180801模拟赛T3

体育成绩统计 / Score 题目描述 正所谓“无体育,不清华”.为了更好地督促同学们进行体育锻炼,更加科学地对同学们进行评价,五道口体校的老师们在体育成绩的考核上可谓是煞费苦心.然而每到学期期末时,面对海量的原始数据,如何对数据进行处理,得到同学们的体育总评成绩却又成了体育部老师的一大难题. 对于大一的同学们来说,体育课的总评成绩由五部分组成:体育课专项成绩(满分50分).长跑测试成绩(满分20分).“阳光长跑”成绩(满分10分).体质测试成绩(满分10分).“大一专项计划”成绩(满分10分)

MapReduce实例:编写MapReduce程序,统计每个买家收藏商品数量

现有某电商网站用户对商品的收藏数据,记录了用户收藏的商品id以及收藏日期,名为buyer_favorite1. buyer_favorite1包含:买家id,商品id,收藏日期这三个字段,数据以“\t”分割,样本数据及格式如下: 买家id   商品id    收藏日期 10181   1000481   2010-04-04 16:54:31 20001   1001597   2010-04-07 15:07:52 20001   1001560   2010-04-07 15:08:27 2

(c语法百题32)成绩统计

内容: 某班共有若干名学生(不大于40),已知他们考试的数学成绩,现需要统计100分.90-99分.80-89分.70-79分.60-69分与不及格各成绩档各有多少人. 输入说明: 第一行 一个整数n,班级人数 以下 n行,每行一个整数,代表数学成绩 输出说明: 共6行,从第一行依次为100分.90-99分.80-89分.70-79分.60-69分与不及格的人数 若没有此分数段人数输出0 输入样例: 2 100 60 输出样例 : 1 0 0 0 1 0 #include <stdio.h>

学生各门课程成绩统计SQL语句大全

学生成绩表(stuscore): 姓名:name 课程:subject 分数:score 学号:stuid 张三 数学 89 1 张三 语文 80 1 张三 英语 70 1 李四 数学 90 2 李四 语文 70 2 李四 英语 80 2 创建表 SET ANSI_NULLS ONGOSET QUOTED_IDENTIFIER ONGOSET ANSI_PADDING ONGOCREATE TABLE [dbo].[stuscore]( [name] [varchar](50) COLLATE

在hadoop上进行编写mapreduce程序,统计关键词在text出现次数

mapreduce的处理过程分为2个阶段,map阶段,和reduce阶段.在要求统计指定文件中的所有单词的出现次数时, map阶段把每个关键词写到一行上以逗号进行分隔,并初始化数量为1(相同的单词hadoop中的map会自动放到一行中) reduce阶段是把每个单词出现的频率统计出来重新写回去. 如代码: package com.clq.hadoop2; import org.apache.hadoop.io.IntWritable; import org.apache.hadoop.io.Lo