使用mapReduce分析简单天气数据

做demo前需要先搭建Hadoop集群,并且有linux基础,可参考 https://www.cnblogs.com/linyufeng/p/10831240.html

 1.引出问题

  给一串数据,找出每年的每个月温度最高的2天。其中有可能包含着相同的数据。

1949-10-01 14:21:02    34c
1949-10-01 19:21:02    38c
1949-10-02 14:01:02    36c
1950-01-01 11:21:02    32c
1950-10-01 12:21:02    37c
1951-12-01 12:21:02    23c
1950-10-02 12:21:02    41c
1950-10-03 12:21:02    27c
1951-07-01 12:21:02    45c
1951-07-02 12:21:02    46c
1951-07-03 12:21:03    47c
1949-10-01 14:21:02    34c
1949-10-01 19:21:02    38c
1949-10-02 14:01:02    36c
1950-01-01 11:21:02    32c
1950-10-01 12:21:02    37c
1951-12-01 12:21:02    23c

  2.分析

   从肉眼去看,这么几条数据,人工也能很快的得出结果,但如果有几百万条呢?所以采用hadoop的mapReduce框架,mapReduce是一个分布式的离线计算框架,流程分为4步骤split---map---shuffle---reduce。用mapReduce去处理这些数据。处理天气数据所需要使用到的有年和月还有温度,最后输出则是要对应相对应的日。所以创建一个天气类。并且实现writableComparable接口,实现其未实现方法。


   

package com.sjt.mr.tq.demo;

import java.io.DataInput;
import java.io.DataOutput;
import java.io.IOException;

import org.apache.hadoop.io.WritableComparable;

public class MyTQ implements WritableComparable<MyTQ>{

    private int year;//年
    private int month;//月
    private int day;//日
    private int wd;//温度

    public int getYear() {
        return year;
    }

    public void setYear(int year) {
        this.year = year;
    }

    public int getMonth() {
        return month;
    }

    public void setMonth(int month) {
        this.month = month;
    }

    public int getDay() {
        return day;
    }

    public void setDay(int day) {
        this.day = day;
    }

    public int getWd() {
        return wd;
    }

    public void setWd(int wd) {
        this.wd = wd;
    }

    @Override
    public void write(DataOutput out) throws IOException {
        out.writeInt(year);
        out.writeInt(month);
        out.writeInt(day);
        out.writeInt(wd);
    }

    @Override
    public void readFields(DataInput in) throws IOException {
        year = in.readInt();
        month = in.readInt();
        day = in.readInt();
        wd = in.readInt();
    }

    @Override
    public int compareTo(MyTQ mytq) {
        //1980-05-02 34c
        //比较年是否相同
        int c1 = Integer.compare(year, mytq.getYear());
        if(c1==0){
            //如果相同则比较月份
            int c2 = Integer.compare(month, mytq.getMonth());
            if(c2==0){
                //如果月份相同则比较温度,使得温度降序排序
                return -Integer.compare(wd, mytq.getWd());
            }
            return c2;
        }
        return c1;
    }

}

  3.Map阶段

   在map的读入阶段,需要把从split中读取的数据做切割处理,并且让对象进行序列化存入磁盘中。

  

package com.sjt.mr.tq.demo;

import java.io.IOException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;

import org.apache.hadoop.io.IntWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Mapper;

public class MyMapper extends Mapper<Object, Text, MyTQ, IntWritable>{

    private MyTQ tqKey=new MyTQ();

    private IntWritable Tvalue=new IntWritable();
    //key记录的是偏移量,value为一行的数据
    @Override
    protected void map(Object key, Text value, Mapper<Object, Text, MyTQ, IntWritable>.Context context)
            throws IOException, InterruptedException {

        try {
            //1980-01-02 18:15:45    34c
            //根据制表符分割 获得 split[0]=1980-01-02 18:15:45 split[1]=34c
            String[] splits =value.toString().split("\t");
            //设值key
            SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd");
            Date date = sdf.parse(splits[0]);
            Calendar calendar = Calendar.getInstance();
            calendar.setTime(date);
            //给tqkey设值
            tqKey.setYear(calendar.get(calendar.YEAR));
            tqKey.setMonth(calendar.get(calendar.MONTH)+1);
            tqKey.setDay(calendar.get(calendar.DAY_OF_MONTH));
            int wd = Integer.parseInt(splits[1].substring(0, splits[1].length()-1));
            tqKey.setWd(wd);
            //设值温度
            Tvalue.set(wd);
        } catch (ParseException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        context.write(tqKey, Tvalue);
    }

}

  4.分组比较器

    调用天气对象的分组比较器会造成一条数据一组的现象,因为条件多了一个天气,所以需要自定义分组比较器。

  

package com.sjt.mr.tq.demo;

import org.apache.hadoop.io.WritableComparable;
import org.apache.hadoop.io.WritableComparator;
//分组比较
public class MyGroupComparator extends WritableComparator{
    //调用父类的构造方法
    public  MyGroupComparator(){
        super(MyTQ.class,true);
    }
    @Override
    public int compare(WritableComparable a, WritableComparable b) {
        MyTQ tq1=(MyTQ)a;
        MyTQ tq2=(MyTQ)b;
        //先比较年 再比较月
        int c1 = Integer.compare(tq1.getYear(), tq2.getYear());
        if(c1==0){
            return Integer.compare(tq1.getMonth(), tq2.getMonth());
        }
        return c1;
    }
}

  5.Reduce阶段 

  reduce阶段需要对数据进行最后的处理,根据前面的排序只需要取出当前所得结果的前两行就是该年某月中的温度最高的两天,当然也不排除当前数据中只有一条数据是该年某月的,而且还要判断是否存在相同的天的温度是否处于前两行。

package com.sjt.mr.tq.demo;

import java.io.IOException;

import org.apache.hadoop.io.IntWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Reducer;

public class MyReduce extends Reducer<MyTQ, IntWritable,Text,IntWritable>{
    private Text key=new Text();
    private IntWritable value=new IntWritable();
    @Override
    protected void reduce(MyTQ mytq, Iterable<IntWritable> values,
            Reducer<MyTQ, IntWritable, Text, IntWritable>.Context context) throws IOException, InterruptedException {
        int flag=0;//计数
        int day=0;//储存日期
        for (IntWritable v : values) {
            //如果计算为0取第一位的年月日:温度
            if(flag==0){
                //设key和value值
                key.set(mytq.getYear()+"-"+mytq.getMonth()+"-"+mytq.getDay()+":");
                value.set(mytq.getWd());
                //给day设值 防止重复天数
                day=mytq.getDay();
                flag++;//计数+1
                context.write(key, value);
            }
            //如果计数为1且日期不和第一次写出的日期不一致
            if(flag!=0&&mytq.getDay()!=day){
                key.set(mytq.getYear()+"-"+mytq.getMonth()+"-"+mytq.getDay()+":");
                value.set(mytq.getWd());
                context.write(key, value);
                break;
            }
        }
    }
}

  6.打包运行

    部分代码省略,可再文章最后查看到项目源代码及数据处理文件。

    并且将打包后的jar包丢入集群,将需要处理的文本储存到hdfs上,命令为:

    

    执行下行命令运行:分析tq.txt文件 MyJob为入口,结果放入output目录下

    

    如果不报错,并且再hdfs的output的目录下出现了下图中的情况说明你成功了。可以对part-r-00000进行下载。

    

    下载的结果如果为下图,则代表运行代码正确。

    

    

  项目源代码及文件路径 https://github.com/shijintao123/Hadoop

  编译报错参考:https://blog.csdn.net/qq_42476731/article/details/90298983

原文地址:https://www.cnblogs.com/mangshebaotang/p/10894410.html

时间: 2024-10-15 16:24:43

使用mapReduce分析简单天气数据的相关文章

MapReduce分析明星微博数据

互联网时代的到来,使得名人的形象变得更加鲜活,也拉近了明星和粉丝之间的距离.歌星.影星.体育明星.作家等名人通过互联网能够轻易实现和粉丝的互动,赚钱也变得前所未有的简单.同时,互联网的飞速发展本身也造就了一批互联网明星,这些人借助新的手段,最大程度发挥了粉丝经济的能量和作用,在互联网时代赚得盆满钵满. 正是基于这样一个大背景,今天我们做一个分析明星微博数据的小项目 1.项目需求 自定义输入格式,将明星微博数据排序后按粉丝数关注数 微博数分别输出到不同文件中. 2.数据集 明星 明星微博名称 粉丝

使用hadoop mapreduce分析mongodb数据

使用hadoop mapreduce分析mongodb数据 (现在很多互联网爬虫将数据存入mongdb中,所以研究了一下,写此文档) 版权声明:本文为yunshuxueyuan原创文章.如需转载请标明出处: http://www.cnblogs.com/sxt-zkys/QQ技术交流群:299142667 一. mongdb的安装和使用 1. 官网下载mongodb-linux-x86_64-rhel70-3.2.9.tgz 2. 解压 (可以配置一下环境变量) 3. 启动服务端 ./mongo

Hadoop初学指南(6)--MapReduce的简单实例及分析

本文在上一节的基础上通过一个简单的MR示例对MapReduce的运行流程进行分析. 假设有两行数据,分别是hello you,hello me,我们要统计其中出现的单词以及每个单词出现的次数. 所得的结果为 hello   2 you     1 me      1 (1)大致运行流畅 1.解析成2个<k,v>,分别是<0, hello you><10, hello me>.调用2次map函数. 2.执行map任务 3.map输出后的数据是:<hello,1>

使用hadoop mapreduce分析mongodb数据:(2)

在上一篇使用hadoop mapreduce分析mongodb数据:(1)中,介绍了如何使用Hadoop MapReduce连接MongoDB数据库以及如何处理数据库,本文结合一个案例来进一步说明Hadoop MapReduce处理MongoDB的细节 原始数据 > db.stackin.find({}) { "_id" : ObjectId("575ce909aa02c3b21f1be0bb"), "summary" : "go

C#+HtmlAgilityPack+XPath带你采集数据(以采集天气数据为例子)

转自原文C#+HtmlAgilityPack+XPath带你采集数据(以采集天气数据为例子) 阅读目录 1.HtmlAgilityPack简介 2.XPath技术介绍与使用 3.采集天气网站案例 4.资源 第一次接触HtmlAgilityPack是在5年前,一些意外,让我从技术部门临时调到销售部门,负责建立一些流程和寻找潜在客户,最后在阿里巴巴找到了很多客户信息,非常全面,刚开始是手动复制到Excel,是真尼玛的累,虽然那个时候C#还很菜,也想能不能通过程序来批量获取(所以平时想法要多才好).几

用Map-Reduce的思维处理数据

在很多人的眼里,Map-Reduce等于Hadoop,没有Hadoop谈Map-Reduce犹如自上谈兵,实则不然,Map-Reduce是一种计算模型,只是非常适合在并行的环境下运行,Hadoop是Map-Reduce的一种实现,没有Hadoop照样可以跑Map-Reduce程序.python就内置有map()和reduce方法(虽然与hadoop的map-reduce有区别). 这篇文章主要介绍如何用python在linux的管道进行map-reduce编程,本文写的所有map-reduce程

简单天气应用开发——自定义TableView

顺利解析JSON数据后,天气数据已经可以随意提取了,现在要做的就是建立一个简单的UI. 实况信息较为简单,几个Lable就可以解决.主要是七天天气预报有点麻烦,那是一个由七个字典构成的数组,需要提取出每一天的数据,再组合之后显示在屏幕上. 考虑到简便性,决定使用TableView加上自定义Cell. 新建dailyCell类,同时建立同名xib文件,拖一个Cell,加上三个Lable - (UITableViewCell *)tableView:(UITableView *)tableView

赵雅智_android系统联系人app分析并获取数据

手机联系人存放位置 和短信一样在data-data下 手机联系人数据库解析 将contacts2.db表导出,通过SQLiteexpert查看 mimetypes表:存放的数据类型(电话,头像,姓名,邮箱) 外键: raw_contacts表:存放联系人的id contact_id:联系人id display_name:联系人姓名 data表:存放联系人的数据 data1:联系人数据 data2:在mimetypes表中data1表示值得意义 mimetype_id:联系人ID,data数据所属

基于Qt的信号分析简单应用软件的设计

一.需求描述: 1.读取data.asc文件,分析其连续性: 2.绘制信号图像,并保存. 二.UI界面组成: 该应用的UI由以下几个控件组成: 3个PushButton:打开文件.图像保存.退出: 1个Combox:下拉框用于信号的选择: 1个Widget:用于确定绘图区域的坐标,并在Widget部件上绘制图像曲线. 3个Label:用于标注注释,及坐标轴 三.主要功能的实现 信号分析结果如下: 其中最主要的涉及信号数据的标准化处理,标准化处理计算公式: std=(当前信号值-此类信号的最小值)