在本博文,我们要学习一个挖掘气象数据的程序。气象数据是通过分布在美国全国各地区的很多气象传感器每隔一小时进行收集,这些数据是半结构化数据且是按照记录方式存储的,因此非常适合使用 MapReduce 程序来统计分析。

  我们使用的数据来自美国国家气候数据中心、美国国家海洋和大气管理局(简称 NCDCNOAA),这些数据按行并以 ASCII 格式存储,其中每一行是一条记录。 下面我们展示一行采样数据,其中重要的字段被突出显示。该行数据被分割成很多行以突出每个字段,但在实际文件中,这些字段被整合成一行且没有任何分隔符。

  MapReduce 任务过程分为两个处理阶段:map 阶段和reduce阶段 。每个阶段都以键值对作为输入和输出,其类型由程序员自己来选择。程序员还需要写两个函数:map 函数和reduce 函数。在这里, map 阶段的输入是 NCDC NOAA 原始数据。我们选择文本格式作为输入格式,将数据集的每一行作为文本输入。键是某一行起始位置相对于文件起始位置的偏移量,不过我们不需要这个信息,所以将其忽略。我们的 map 函数很简单。由于我们只对气象站和气温感兴趣,所以只需要取出这两个字段数据。在本博文中,map 函数只是一个数据准备阶段, 通过这种方式来准备数据,使reducer 函数能够继续对它进行处理:即统计出每个气象站 30 年来的平均气温。map 函数还是一个比较合适去除已损记录的地方,在 map 函数里面,我们可以筛掉缺失的或者错误的气温数据。

  我们明白 MapReduce 程序的工作原理之后,下一步就是写代码实现它。我们需要编写三块代码内容:一个 map 函数、一个 reduce 函数和一些用来运行作业的代码。map 函数由 Mapper 类实现来表示,Mapper 声明一个 map() 虚方法,其内容由我们自己来实现。
  下面我们来编写 Mapper 类,实现 map() 方法,提取气象站和气温数据。

package com.hadoop.test;

import java.io.IOException;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.util.Tool;
import org.apache.hadoop.util.ToolRunner;
import org.apache.hadoop.conf.Configured;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.io.IntWritable;
import org.apache.hadoop.io.LongWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.lib.input.FileInputFormat;
import org.apache.hadoop.mapreduce.lib.input.FileSplit;
import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat;
import org.apache.hadoop.mapreduce.Job;
import org.apache.hadoop.mapreduce.Mapper;
import org.apache.hadoop.mapreduce.Reducer; /**
*
* 统计美国每个气象站30年来的平均气温
* 1.编写map()函数
* 2.编写reduce()函数
* 3.编写run()执行方法,负责运行MapReduce作业
* 4.在main()方法中运行程序
*
*/
public class Temperature extends Configured implements Tool{ //定义TemperatureMapper继承自Mapper类,并在其中实现map()函数;
//Mapper<>接口的数据类型为:Mapper<输入可有值相当于Java的int类型,输入value值相当于Java的String类型,输出key值,输出value值>
public static class TemperatureMapper extends Mapper<LongWritable, Text, Text, IntWritable>{
public void map(LongWritable key, Text value, Context context) throws IOException, InterruptedException{//Context实例用于键值对的输出
//第一步:将每行气象站数据转换为String类型
String line = value.toString(); //第二步:提取气温值
int temperature = Integer.parseInt(line.substring(, ).trim()); if (temperature != -) {
//第三步:获取气象站编号
//通过context实例获取数据分片
FileSplit fileSplit = (FileSplit) context.getInputSplit();
//然后获取气象站编号
String weatherStationId = fileSplit.getPath().getName().substring(, ); //第四步:输出数据
context.write(new Text(weatherStationId), new IntWritable(temperature));
} }
} public static class TemperatureReducer extends Reducer<Text, IntWritable, Text, IntWritable> {
private IntWritable result = new IntWritable();
public void reduce(Text key, Iterable<IntWritable> values, Context context) throws IOException, InterruptedException{ //统计气象站的所有气温值
int sum = ;
int count = ;
for(IntWritable val:values) {
//对所有气温值累加
sum += val.get();
//统计集合大小
count++;
} //第二步:求同一个气象站的平均气温
result.set(sum/count); //第三步:输出数据
context.write(key, result);
}
} public static void main(String[] args) throws Exception {
// TODO Auto-generated method stub
//输入输出路径
String[] args0 = {args[], args[]};//该写法用于在Hadoop集群上进行测试,如果在Eclipse上进行测试请采用下一行的写法
//{"hdfs://Centpy:9000/weather/", "hdfs://Centpy:9000/weather/output"};
//执行
int ec = ToolRunner.run(new Configuration(), new Temperature(), args0);
System.exit(ec);
} @Override
public int run(String[] arg0) throws Exception{
// TODO Auto-generated method stub
//第一步:读取配置文件
Configuration conf = new Configuration(); //第二步:如果输出路径已经存在,则删除
Path mypath =new Path(arg0[]);
FileSystem hdfs = mypath.getFileSystem(conf);
if (hdfs.isDirectory(mypath)) {
hdfs.delete(mypath, true);
} //第三步:构建Job对象
Job job = new Job(conf, "temperature");
job.setJarByClass(Temperature.class); //第四步:指定数据的输入输出路径
FileInputFormat.addInputPath(job, new Path(arg0[]));
FileOutputFormat.setOutputPath(job, new Path(arg0[])); //第五步:指定Mapper和Reducer
job.setMapperClass(TemperatureMapper.class);
job.setReducerClass(TemperatureReducer.class); //第六步:设置map()函数和reducer()函数输出类型
job.setOutputKeyClass(Text.class);
job.setOutputValueClass(IntWritable.class); //第七步:提交作业
job.waitForCompletion(true);
return ;
} }

  写完之后我们需要将其导出为JAR包。

  然后上传到Hadoop集群上Hadoop的安装路径下(可用cd $HADOOP_HOME命令快速进入目录),然后使用rz命令上传,如果没装rz命令请先运行命令:

  yum -y install lrzsz

  然后找到刚才导出的JAR包确认上传。

  最后,执行运行命令:

  hadoop jar Temperature.jar com.hadoop.test.Temperature /weather /weatherOutput //  第一个jar表示运行的对象是jar文件
                                          // .jar文件为我们要运行的jar文件
                                          // com.hadoop.test.Temperature为类的路径,注意请写全
                                          // /weather表示我们的输入文件,对应代码中的args[0]
                                          // /weatherOutput表示我的输出文件,对应代码中的args[1],注意必须是不存在的路径

  运行结果如下:

 以上就是博主为大家介绍的这一板块的主要内容,这都是博主自己的学习过程,希望能给大家带来一定的指导作用,有用的还望大家点个支持,如果对你没用也望包涵,有错误烦请指出。如有期待可关注博主以第一时间获取更新哦,谢谢!

版权声明:本文为博主原创文章,未经博主允许不得转载。

MapReduce项目之气温统计的更多相关文章

  1. [MapReduce_add_2] MapReduce 实现年度最高气温统计

    0. 说明 编写 MapReduce 程序实现年度最高气温统计 1. 气温数据分析 气温数据样例如下: ++023450FM-+000599999V0202701N015919999999N00000 ...

  2. 在eclipse中用gradle搭建MapReduce项目

    我用的系统是ubuntu14.04新建一个Java Project. 这里用的是gradle打包,gradle默认找src/main/java下的类编译.src目录已经有了,手动在src下创建main ...

  3. ubuntu14.04 Hadoop单机开发环境搭建MapReduce项目

    Hadoop官网:http://hadoop.apache.org/ 目前最新的版本是Hadoop 3.0.0-alpha1前提:java 1.6 版本以上 首先从官网下载压缩包(hadoop-3.0 ...

  4. [Hive_add_7] Hive 实现最高气温统计

    0. 说明 Hive 通过 substr() 函数实现最高气温统计 1. Hive 实现最高气温统计 1.1 思路 将一行文本加载为 String 通过 substr() 函数截取年份和温度 1.2 ...

  5. [Demo_01] MapReduce 实现密码 Top10 统计

    0. 说明 通过 MapReduce 实现密码 Top10 统计 通过两次 MapReduce 实现 1. 流程图 2. 程序编写 密码 Top10 统计代码

  6. 通过Maven管理多个MapReduce项目

    1. 配置Maven环境 首先检查Windows是否配置了maven,进入cmd命令行,输入mvn -version命令,如果出现下图所示的 情形则表示满意配置maven. 从浏览器进入maven官网 ...

  7. MapReduce明星搜索指数统计,找出人气王

    我们继续通过项目强化掌握Combiner和Partitioner优化Hadoop性能 1.项目介绍 本项目我们使用明星搜索指数数据,分别统计出搜索指数最高的男明星和女明星. 2.数据集 3.分析 基于 ...

  8. MapReduce实战:邮箱统计及多输出格式实现

    紧接着上一篇博文我们学习了MapReduce得到输出格式之后,在这篇博文里,我们将通过一个实战小项目来熟悉一下MultipleOutputs(多输出)格式的用法. 项目需求: 假如这里有一份邮箱数据文 ...

  9. MapReduce的手机流量统计的案例

    程序:(另外一个关于单词计数的总结:http://www.cnblogs.com/DreamDrive/p/5492572.html) import java.io.IOException; impo ...

随机推荐

  1. 前端多媒体(1)——获取摄像头&麦克风

    捕获视频/音频 PPT地址 长久以来,音频/视频捕获都是网络开发中的"圣杯".多年来,我们总是依赖于浏览器插件(Flash 或 Silverlight)实现这一点. 依靠 WebR ...

  2. EVC入门之二: 在未被加载的DLL中设置断点 (虽然没有遇到这个问题,不过先摘抄下来)

    问题: 这个问题居然也郁闷了我一段时间. 我们假设在EVC里建立了一个project, 里面有SubProject_1(以下简称SB1,嘿嘿), 编译生成一个EXE; SubProject_2(以下简 ...

  3. UC Bug

    出现bug时,假如把A代码段删了,bug消失,那么此bug是不是一定就是A代码段导致的呢?接着写B代码段,同样bug再现,那么此bug是不是一定就是B代码段导致的呢? 未必,可能是Base代码段和A. ...

  4. CodeForces - 613D:Kingdom and its Cities(虚树+DP)

    Meanwhile, the kingdom of K is getting ready for the marriage of the King's daughter. However, in or ...

  5. [Selenium] 处理表格(python + java)

    python : https://www.cnblogs.com/yan-xiang/p/6819168.html 操作内容:获取table总行数.总列数.获取某单元格的text值,删除一行[如果每行 ...

  6. Scrapy,终端startproject,显示错误TimeoutError: [WinError 10060] 由于连接方在一段时间后没有正确答复或连接的主机没有反应,连接尝试失败。

    F:\python_project\test>scrapy startproject spz Traceback (most recent call last): File "d:\p ...

  7. bzoj1177&p3625 [APIO2009]采油区域p[大力讨论]

    我好菜菜啊. 给定矩形,从中选出三个边长K的正方形互不重叠,使得覆盖到的数总和最大. 想的时候往dp上钻去了..结果一开始想了一个错的dp,像这样 /************************* ...

  8. hdu3518 Boring Counting[后缀排序]

    裸的统计不同的重复出现子串(不重叠)种数的题.多次使用后缀排序要注意小细节.y数组在重复使用时一定要清空,看那个line25 +k就明白了 ,cnt也要清空,为什么就不说了 #include<b ...

  9. Xshell 主机和远程机之间的文件传输

    (1)宿主机传输文件到远程机 方法1:直接拖动文件至xshell远程机命令行界面 方法2:远程机命令行输入rz打开文件选择框 (2)远程机传输文件到宿主机 远程机命令行界面上输入sz xxx.txt( ...

  10. Http客户端跳转和服务器端跳转的区别

    服务器端跳转:      服务器转发全程是没有客户端参与的,都在web container容器内部进行,没有任何服务器和客户端的通信,实际就是服务器内部的跳转. 这次forward, 服务器没有构建H ...