武汉纺织大学
《Haoop 应用开发》大作业
2014-2016 年全球气温统计和分析
成
学
姓
班
绩:
号:
名:
级:
1704240902
崔春霞
软件 11705
指导教师:
梁晶
报告日期:2019 年 11 月 26 日
1、课程设计题目及要求
(1)从 ftp://ftp.ncdc.noaa.gov/pub/data/gsod 下载 2014 到 206 年的天
气数据,然后对数据进行清洗,仅保留日期和当天的气温,数据文件保存为
temperature.txt;
(2)根据 temperature.txt,统计全球每年的最高气温和最低气温;要求:
按每年每月统计最高和最低气温;按每年每月统计平均气温,并按年月由近到远
排序;按年月筛选 15-25 度之间的气温数据,并按 2014 到 2016 年分别存储到 3
个文件中。
(3)需要提交纸质作业报告,以及程序和数据文件的电子档。
2、课程设计各个模块的主要功能描述
(1)课程设计实验流程图:
图 2.1 流程图
(2)本次课程设计共分为两个模块,即数据处理以及统计分析。
1>数据处理:该部分使用的是 python 语言,首先从下载 2014-2016 年的文件,
之后在 linux 命令行下使用 gunzip 解压全都压缩文件,之后剔除每个小文件的
标签列,使用 cat 命令归划到一个文件中;之后在 windows 环境下使用 python
语言进行数据清理,主要原理是以行的形式读取文件,之后按空格分割,将所需
要的字段添加到列表中,之后保存在 data.txt 文件里。
2>统计分析:该部分使用的是 scala 语言,在统计每年每月最高、低温度时主要
使用 groupByKey()将具有相同键的值进行分组,之后使用 mapValues()对 RDD 中
的值进行操作,使用 max,min 方法选取最值;平均温度使用 combineByKey()合
并相同键的值,之后分别使用 map()及 sortBy()求平均值和排序;筛选温度值时
主要使用 filter()分别对使用 startsWith()筛选后每年的数据进行筛选,之后
再将数据保存在 3 个文件里。
3、主要代码和输出结果(使用 scala 语言)
(1)筛选出每年的日期与当天温度
①在 linux 中下载三个压缩文件并解压,在命令行里使用解压命令“gunzip *”
解压所有的小压缩文件,使用“sed -i ‘id’ * ”剔除所有的解压后的小文件
的行首,再使用“cat *>>../data.txt”将所有的小文件合并的一个文件中去。
解压过程结果如图:
图 3.1 解压命令
图 3.2 解压前
②在 windows 中使用 python 语言找出所需要的数据
图 3.3 解压后
代码:
import codecs
f = codecs.open(r'D:\data.txt', mode='r', encoding='utf-8') # 打开 txt
文件,以‘utf-8'编码读取
line = f.readline()
# 以行的形式进行读取文件
list1 = []
while line:
a = line.split()
b = a[2:4]
# 这是选取需要读取的位数
list1.append(b) # 将其添加在列表之中
line = f.readline()
f.close()
print(list1[1])
def text_save(filename, data):#filename 为写入 CSV 文件的路径,data 为要
写入数据列表.
file = open(filename,'a')
for i in range(len(data)):
s = str(data[i]).replace('[','').replace(']','')#去除[],这两行
按数据不同,可以选择
s = s.replace("'",'').replace(',','') +'\n'
#去除单引号,逗
号,每行末尾追加换行符
file.write(s)
file.close()
print("保存文件成功")
text_save(r'D:\data1.txt',list1)
保存后的文件内容:
(2) 统计分析
图 3.4 分析所需的数据
0>数据处理:由于实验时使用的是老师已经处理好的数据,此数据集包括
2014-2018 年的数据,故对此数据集进行筛选得到 2014-2016 年的数据,使用的
是 Scala 语言,具体如下:
①首先读取文件,以行的形式读取,行分割时使用空格分割,读文件时由于只
需要年月,所以使用 substring()进行分割保留每行读取的第 1 个字符岸串的前
6 个字符。
相关代码:
//读取已经处理过的文件,并转化为所需要的格式
val
input=sc.textFile("file:///home/jkx/data/hadoop/temperature.txt").map
{x=>val line=x.split(" ");(line(0).substring(0,6),line(1).toFloat)}
//查看前 5 个
input.take(5)
成功读取后的结果及运行过程:
②使用 startWith()以及 filter 分别筛选出以 2014,2015,2016 开头的数据,
图 3.1 读文件
再使用 union 合并这三个文件。
相关代码:
//分别选取 2014.2015.2016 年的数据
val temp1=input.filter(x=>x._1.startsWith("2014"))
val temp2=input.filter(x=>x._1.startsWith("2015"))
val temp3=input.filter(x=>x._1.startsWith("2016"))
//合并数据
val temp=temp1.union(temp2).union(temp3)
//查看前 10 个
temp.take(10)
筛选成功:
合并成功并查看结果:
图 3.2 筛选 2014/5/6 数据
1>全球每年的最高气温和最低气温
图 3.3 最终需要处理的数据集
①由于数据集读取时本身就是 RDD 形式,所以可以使用转换操作 groupByKey()
将具有相同键的值进行分组。
相关代码:
//将具有相同键的值进行分组
val t=temp.groupByKey()
//查看前 1 个
t.take(1)
分组成功并查看结果:
②每年每月最高气温:使用 mapValues 进行操作 RDD 中的值,使用 max 方法得
图 3.4 分组成功后的 RDD
到每个值中的最大数
相关代码:
//选取每个值的最大数
val tempmax=t.mapValues(x=>x.max)
//查看前 5 个
tempmax.take(5)
成功结果及查看数据:
③每年每月最低气温:使用 mapValues 进行操作 RDD 中的值,使用 min 方法得到
图 3.5 最高气温
每个值中的最小数
相关代码:
//选取每个值的最大数
val tempmin=t.mapValues(x=>x.min)
//查看前 5 个
tempmin.take(5)
成功结果及查看数据:
④使用 union 合并最值数据并保存
图 3.6 最低气温