2021-06-09

广州商学院

课程论文

题目: 使用python和spark对2020年美国新冠肺炎疫情数据分析

课 程 名 称 大数据技术与应用
考 查 学 期 2020-2021第2学期
考 查 方 式 考查(设计)
姓 名 何泽浩
学 号 201806110094
专 业 计科1802
成 绩
指 导 教 师 吉立建

一、实验平台搭建
1、安装Linux Ubuntu Kylin 16.04(因数据集较大,建议内存为3G)
2、安装Hadoop 3.1.3 安装教程
3、安装Python 3.5(已自带Python 3.5)
4、安装Spark 2.4.0 安装教程
5、配置Python与Spark的交互 安装教程
6、安装Anaconda和Jupyter Notebook 安装教程
二、数据集
本次作业使用的数据集来自数据网站Kaggle的美国新冠肺炎疫情数据集,该数据集以数据表us-counties.csv组织,其中包含了美国发现首例新冠肺炎确诊病例至今(2020-05-19)的相关数据。数据包含以下字段:
2.1 数据集下载
字段名称 字段含义
例如:
date 日期 2020/1/21;2020/1/22;etc
county 区县(州的下一级单位) Snohomish;
state 州 Washington
cases 截止该日期该区县的累计确诊人数 1,2,3…
deaths 截止该日期该区县的累计确诊人数 1,2,3…

2.2 格式转换 :
import pandas as pd
#.csv->.txt
data = pd.read_csv(’/home/hadoop/us-counties.csv’)
with open(’/home/hadoop/us-counties.txt’,‘a+’,encoding=‘utf-8’) as f:
for line in data.values:
f.write((str(line[0])+’\t’+str(line[1])+’\t’
+str(line[2])+’\t’+str(line[3])+’\t’+str(line[4])+’\n’))
原始数据集是以.csv文件组织的,为了方便spark读取生成RDD或者DataFrame,首先将us-counties.csv转换为.txt格式文件us-counties.txt。转换操作使用python实现,代码组织在toTxt.py中,具体代码如下:

转换后结果:

2.3 将文件上传到HDFS文件系统中:
然后使用如下命令把本地文件系统的“/home/hadoop/us-counties.txt”上传到HDFS文件系统中,具体路径是“/user/hadoop/us-counties.txt”。具体命令如下:
./bin/hdfs dfs -put /home/hadoop/us-counties.txt /user/hadoop

三、数使用Spark对数据进行分析
3.1读取文件生成DataFrame:
由于本实验中使用的数据为结构化数据,因此可以使用spark读取源文件生成DataFrame以方便进行后续分析实现。本部分代码组织在analyst.py中,读取us-counties.txt生成DataFrame的代码如下:
from pyspark import SparkConf,SparkContext
from pyspark.sql import Row
from pyspark.sql.types import *
from pyspark.sql import SparkSession
from datetime import datetime
import pyspark.sql.functions as func

def toDate(inputStr):
newStr = “”
if len(inputStr) == 8:
s1 = inputStr[0:4]
s2 = inputStr[5:6]
s3 = inputStr[7]
newStr = s1+"-"+“0”+s2+"-"+“0”+s3
else:
s1 = inputStr[0:4]
s2 = inputStr[5:6]
s3 = inputStr[7:]
newStr = s1+"-"+“0”+s2+"-"+s3
date = datetime.strptime(newStr, “%Y-%m-%d”)
return date

#主程序:
spark = SparkSession.builder.config(conf = SparkConf()).getOrCreate()

fields = [StructField(“date”, DateType(),False),StructField(“county”, StringType(),False),StructField(“state”, StringType(),False),
StructField(“cases”, IntegerType(),False),StructField(“deaths”, IntegerType(),False),]
schema = StructType(fields)

rdd0 = spark.sparkContext.textFile("/user/hadoop/us-counties.txt")
rdd1 = rdd0.map(lambda x:x.split("\t")).map(lambda p: Row(toDate(p[0]),p[1],p[2],int(p[3]),int(p[4])))

shemaUsInfo = spark.createDataFrame(rdd1,schema)
shemaUsInfo.createOrReplaceTempView(“usInfo”)

print(‘Test,From XxJison!’) # 对此次程序是否已经完成运行进行判断,若执行此行证明执行完毕

3.2 对数据进行分析:
本实验主要统计以下8个指标,分别是:
1、统计美国截止每日的累计确诊人数和累计死亡人数。做法是以date作为分组字段,对cases和deaths字段进行汇总统计。
#1.计算每日的累计确诊病例数和死亡数
df=shemaUsInfo.groupBy(“date”).agg(func.sum(“cases”),func.sum(“deaths”)).sort(shemaUsInfo[“date”].asc())
#列重命名
df1=df.withColumnRenamed(“sum(cases)”,“cases”).withColumnRenamed(“sum(deaths)”,“deaths”)
df1.repartition(1).write.json(“result1.json”) #写入hdfs

#注册为临时表供下一步使用
df1.createOrReplaceTempView(“ustotal”)

2、统计美国每日的新增确诊人数和新增死亡人数。因为新增数=今日数-昨日数,所以考虑使用自连接,连接条件是t1.date = t2.date + 1,然后使用t1.totalCases – t2.totalCases计算该日新增。
#2.计算每日较昨日的新增确诊病例数和死亡病例数
df2 = spark.sql(“select t1.date,t1.cases-t2.cases as caseIncrease,t1.deaths-t2.deaths as deathIncrease from ustotal t1,ustotal t2 where t1.date = date_add(t2.date,1)”)

df2.sort(df2[“date”].asc()).repartition(1).write.json(“result2.json”) #写入hdfs

3、统计截止5.19日,美国各州的累计确诊人数和死亡人数。首先筛选出5.19日的数据,然后以state作为分组字段,对cases和deaths字段进行汇总统计。
#3.统计截止5.19日 美国各州的累计确诊人数和死亡人数
df3 = spark.sql(“select date,state,sum(cases) as totalCases,sum(deaths) as totalDeaths,round(sum(deaths)/sum(cases),4) as deathRate from usInfo where date = to_date(‘2020-05-19’,‘yyyy-MM-dd’) group by date,state”)

df3.sort(df3[“totalCases”].desc()).repartition(1).write.json(“result3.json”) #写入hdfs

df3.createOrReplaceTempView(“eachStateInfo”)

4、统计截止5.19日,美国确诊人数最多的十个州。对3)的结果DataFrame注册临时表,然后按确诊人数降序排列,并取前10个州。
#4.找出美国确诊最多的10个州
df4 = spark.sql(“select date,state,totalCases from eachStateInfo order by totalCases desc limit 10”)

df4.repartition(1).write.json(“result4.json”)

5、统计截止5.19日,美国死亡人数最多的十个州。对3)的结果DataFrame注册临时表,然后按死亡人数降序排列,并取前10个州。
#5.找出美国死亡最多的10个州
df5 = spark.sql(“select date,state,totalDeaths from eachStateInfo order by totalDeaths desc limit 10”)
df5.repartition(1).write.json(“result5.json”)

6、统计截止5.19日,美国确诊人数最少的十个州。对3)的结果DataFrame注册临时表,然后按确诊人数升序排列,并取前10个州。
#6.找出美国确诊最少的10个州
df6 = spark.sql(“select date,state,totalCases from eachStateInfo order by totalCases asc limit 10”)
df6.repartition(1).write.json(“result6.json”)

7、统计截止5.19日,美国死亡人数最少的十个州。对3)的结果DataFrame注册临时表,然后按死亡人数升序排列,并取前10个州。
#7.找出美国死亡最少的10个州
df7 = spark.sql(“select date,state,totalDeaths from eachStateInfo order by totalDeaths asc limit 10”)
df7.repartition(1).write.json(“result7.json”)

8、统计截止5.19日,全美和各州的病死率。病死率 = 死亡数/确诊数,对3)的结果DataFrame注册临时表,然后按公式计算。
#8.统计截止5.19全美和各州的病死率
df8=spark.sql(“select 1 as sign,date,‘USA’ as state,round(sum(totalDeaths)/sum(totalCases),4) as deathRate from eachStateInfo group by date union select 2 as sign,date,state,deathRate from eachStateInfo”).cache()
df8.sort(df8[“sign”].asc(),df8[“deathRate”].desc()).repartition(1).write.json(“result8.json”)

在计算以上几个指标过程中,根据实现的简易程度,既采用了DataFrame自带的操作函数,又采用了spark sql进行操作。
3.3 结果文件:
查看终端是否存在文件:

上述Spark计算结果保存.json文件,方便后续可视化处理。由于使用Python读取HDFS文件系统不太方便,故将HDFS上结果文件转储到本地文件系统中,使用以下命令:
./bin/hdfs dfs -get /user/hadoop/result1.json/*.json /home/hadoop/result/result1

四、数据可视化
4.1 可视化工具选择与代码:
选择使用python第三方库pyecharts作为可视化工具。在使用前,需要安装pyecharts,安装代码如下:
pip install pyecharts
具体可视化实现代码组织与showdata.py文件中。具体代码如下:
from pyecharts import options as opts
from pyecharts.charts import Bar
from pyecharts.charts import Line
from pyecharts.components import Table
from pyecharts.charts import WordCloud
from pyecharts.charts import Pie
from pyecharts.charts import Funnel
from pyecharts.charts import Scatter
from pyecharts.charts import PictorialBar
from pyecharts.options import ComponentTitleOpts
from pyecharts.globals import SymbolType
import json

#1.画出每日的累计确诊病例数和死亡数——>双柱状图
def drawChart_1(index):
root = “/home/hadoop/result/result” + str(index) +"/part-00000-ec40b67a-7af9-460c-8b99-73e00f7435dd-c000.json"
date = []
cases = []
deaths = []
with open(root, ‘r’) as f:
while True:
line = f.readline()
if not line: # 到 EOF,返回空字符串,则终止循环
break
js = json.loads(line)
date.append(str(js[‘date’]))
cases.append(int(js[‘cases’]))
deaths.append(int(js[‘deaths’]))
d = (
Bar()
.add_xaxis(date)
.add_yaxis(“累计确诊人数”, cases, stack=“stack1”)
.add_yaxis(“累计死亡人数”, deaths, stack=“stack1”)
.set_series_opts(label_opts=opts.LabelOpts(is_show=False))
.set_global_opts(title_opts=opts.TitleOpts(title=“美国每日累计确诊和死亡人数”))
.render("/home/hadoop/result/result1/result1.html")
)
#2.画出每日的新增确诊病例数和死亡数——>折线图
def drawChart_2(index):
root = “/home/hadoop/result/result” + str(index) +"/part-00000-67b77e57-fbce-4a51-96b1-c1c738f38147-c000.json"
date = []
cases = []
deaths = []
with open(root, ‘r’) as f:
while True:
line = f.readline()
if not line: # 到 EOF,返回空字符串,则终止循环
break
js = json.loads(line)
date.append(str(js[‘date’]))
cases.append(int(js[‘caseIncrease’]))
deaths.append(int(js[‘deathIncrease’]))
(
Line(init_opts=opts.InitOpts(width=“1600px”, height=“800px”))
.add_xaxis(xaxis_data=date)
.add_yaxis(
series_name=“新增确诊”,
y_axis=cases,
markpoint_opts=opts.MarkPointOpts(
data=[
opts.MarkPointItem(type_=“max”, name=“最大值”)

        ]
    ),
    markline_opts=opts.MarkLineOpts(
        data=[opts.MarkLineItem(type_="average", name="平均值")]
    ),
)
.set_global_opts(
    title_opts=opts.TitleOpts(title="美国每日新增确诊折线图", subtitle=""),
    tooltip_opts=opts.TooltipOpts(trigger="axis"),
    toolbox_opts=opts.ToolboxOpts(is_show=True),
    xaxis_opts=opts.AxisOpts(type_="category", boundary_gap=False),
)
.render("/home/hadoop/result/result2/result1.html")
)
(
Line(init_opts=opts.InitOpts(width="1600px", height="800px"))
.add_xaxis(xaxis_data=date)
.add_yaxis(
    series_name="新增死亡",
    y_axis=deaths,
    markpoint_opts=opts.MarkPointOpts(
        data=[opts.MarkPointItem(type_="max", name="最大值")]
    ),
    markline_opts=opts.MarkLineOpts(
        data=[
            opts.MarkLineItem(type_="average", name="平均值"),
            opts.MarkLineItem(symbol="none", x="90%", y="max"),
            opts.MarkLineItem(symbol="circle", type_="max", name="最高点"),
        ]
    ),
)
.set_global_opts(
    title_opts=opts.TitleOpts(title="美国每日新增死亡折线图", subtitle=""),
    tooltip_opts=opts.TooltipOpts(trigger="axis"),
    toolbox_opts=opts.ToolboxOpts(is_show=True),
    xaxis_opts=opts.AxisOpts(type_="category", boundary_gap=False),
)
.render("/home/hadoop/result/result2/result2.html")
)

#3.画出截止5.19,美国各州累计确诊、死亡人数和病死率—>表格
def drawChart_3(index):
root = “/home/hadoop/result/result” + str(index) +"/part-00000-d91e2e3a-128a-4565-a08c-dc518f7e2dca-c000.json"
allState = []
with open(root, ‘r’) as f:
while True:
line = f.readline()
if not line: # 到 EOF,返回空字符串,则终止循环
break
js = json.loads(line)
row = []
row.append(str(js[‘state’]))
row.append(int(js[‘totalCases’]))
row.append(int(js[‘totalDeaths’]))
row.append(float(js[‘deathRate’]))
allState.append(row)
table = Table()
headers = [“State name”, “Total cases”, “Total deaths”, “Death rate”]
rows = allState
table.add(headers, rows)
table.set_global_opts(
title_opts=ComponentTitleOpts(title=“美国各州疫情一览”, subtitle="")
)
table.render("/home/hadoop/result/result3/result1.html")
#4.画出美国确诊最多的10个州——>词云图
def drawChart_4(index):
root = “/home/hadoop/result/result” + str(index) +"/part-00000-8ac5a4fe-33bf-4263-9cb4-48477fadee20-c000.json"
data = []
with open(root, ‘r’) as f:
while True:
line = f.readline()
if not line: # 到 EOF,返回空字符串,则终止循环
break
js = json.loads(line)
row=(str(js[‘state’]),int(js[‘totalCases’]))
data.append(row)
c = (
WordCloud()
.add("", data, word_size_range=[20, 100], shape=SymbolType.DIAMOND)
.set_global_opts(title_opts=opts.TitleOpts(title=“美国各州确诊Top10”))
.render("/home/hadoop/result/result4/result1.html")
)
#5.画出美国死亡最多的10个州——>象柱状图
def drawChart_5(index):
root = “/home/hadoop/result/result” + str(index) +"/part-00000-b88cbd17-d301-4493-89bd-3c1dbdb21843-c000.json"
state = []
totalDeath = []
with open(root, ‘r’) as f:
while True:
line = f.readline()
if not line: # 到 EOF,返回空字符串,则终止循环
break
js = json.loads(line)
state.insert(0,str(js[‘state’]))
totalDeath.insert(0,int(js[‘totalDeaths’]))
c = (
PictorialBar()
.add_xaxis(state)
.add_yaxis(
“”,
totalDeath,
label_opts=opts.LabelOpts(is_show=False),
symbol_size=18,
symbol_repeat=“fixed”,
symbol_offset=[0, 0],
is_symbol_clip=True,
symbol=SymbolType.ROUND_RECT,
)
.reversal_axis()
.set_global_opts(
title_opts=opts.TitleOpts(title=“PictorialBar-美国各州死亡人数Top10”),
xaxis_opts=opts.AxisOpts(is_show=False),
yaxis_opts=opts.AxisOpts(
axistick_opts=opts.AxisTickOpts(is_show=False),
axisline_opts=opts.AxisLineOpts(
linestyle_opts=opts.LineStyleOpts(opacity=0)
),
),
)
.render("/home/hadoop/result/result5/result1.html")
)
#6.找出美国确诊最少的10个州——>词云图
def drawChart_6(index):
root = “/home/hadoop/result/result” + str(index) +"/part-00000-603ea052-ba9e-4fbc-a7f2-879fb539def2-c000.json"
data = []
with open(root, ‘r’) as f:
while True:
line = f.readline()
if not line: # 到 EOF,返回空字符串,则终止循环
break
js = json.loads(line)
row=(str(js[‘state’]),int(js[‘totalCases’]))
data.append(row)
c = (
WordCloud()
.add("", data, word_size_range=[100, 20], shape=SymbolType.DIAMOND)
.set_global_opts(title_opts=opts.TitleOpts(title=“美国各州确诊最少的10个州”))
.render("/home/hadoop/result/result6/result1.html")
)
#7.找出美国死亡最少的10个州——>漏斗图
def drawChart_7(index):
root = “/home/hadoop/result/result” + str(index) +"/part-00000-ef286e03-398b-4e09-b8e8-1b7d97b7b37d-c000.json"
data = []
with open(root, ‘r’) as f:
while True:
line = f.readline()
if not line: # 到 EOF,返回空字符串,则终止循环
break
js = json.loads(line)
data.insert(0,[str(js[‘state’]),int(js[‘totalDeaths’])])
c = (
Funnel()
.add(
“State”,
data,
sort_=“ascending”,
label_opts=opts.LabelOpts(position=“inside”),
)
.set_global_opts(title_opts=opts.TitleOpts(title=""))
.render("/home/hadoop/result/result7/result1.html")
)
#8.美国的病死率—>饼状图
def drawChart_8(index):
root = “/home/hadoop/result/result” + str(index) +"/part-00000-d02e80bc-bfa3-4f80-ad67-bc4cc5fbbc63-c000.json"
values = []
with open(root, ‘r’) as f:
while True:
line = f.readline()
if not line: # 到 EOF,返回空字符串,则终止循环
break
js = json.loads(line)
if str(js[‘state’])==“USA”:
values.append([“Death(%)”,round(float(js[‘deathRate’])*100,2)])
values.append([“No-Death(%)”,100-round(float(js[‘deathRate’])*100,2)])
c = (
Pie()
.add("", values)
.set_colors([“blcak”,“orange”])
.set_global_opts(title_opts=opts.TitleOpts(title=“全美的病死率”))
.set_series_opts(label_opts=opts.LabelOpts(formatter="{b}: {c}"))
.render("/home/hadoop/result/result8/result1.html")
)
#可视化主程序:
index = 1
while index<9:
funcStr = “drawChart_” + str(index)
eval(funcStr)(index)
index+=1

五、结果截图
可视化结果是.html格式的,reslut1的结果展示图保存路径为“/home/hadoop/result/result1/result1.html”,reslut2的结果展示图保存路径为“/home/hadoop/result/result2/result1.html”,其余类似递推。具体截图如下:
5.1 美国每日的累计确诊病例数和死亡数——>双柱状图

5.2 美国每日的新增确诊病例数——>折线图

5.3 美国每日的新增死亡病例数——>折线图

5.4 截止5.19,美国各州累计确诊、死亡人数和病死率—>表格

5.5 截止5.19,美国累计确诊人数前10的州—>词云图

5.6 截止5.19,美国累计死亡人数前10的州—>象柱状图

5.7 截止5.19,美国累计确诊人数最少的10个州—>词云图

5.8 截止5.19,美国累计死亡人数最少的10个州—>漏斗图

5.9 截止2020.5.19,美国的病死率—>饼状图

六、经验总结
通过本次实验,能够把我们在这一学期学的内容融会贯通,在这学期我们前期进行了python语言的巩固,对于之前的知识进行了回忆,中期对spark进行了学习,结合python,在实操过程中使用pyspark进行了操作,对RDD和DataFrame都有所涉略。在本次实验中,我们使用RDD对txt文件进行了处理,再用DataFrame对数据进行了分析,结合数据库语言,对数据进行处理,使得生成的json文件能够是我们想要的结果,其次我们对json文件进行了可视化处理,在这之中使用了pyecharts可视化第三方工具,这个工具也是我在本次实验中第一次用到,对该工具的使用不太熟,希望在以后的学习中能够对该工具的使用更加的熟练,通过这个可视化工具,我们可以得到html文件,这个文件就是可视化的结果。在本次实验中遇到了些许难题,比如在系统环境中出现了错误,导致系统要重新安装,也遇到过在运行python文件时,代码报错,经检查发现是配置文件配置错误导致的,在这个实验中,最大的问题就是要处理好环境的问题,只要将环境配置正确,基本不会有太大的问题,在本次实验中遇到的问题希望在以后能够加以改进,继续加强自己的基础学习。
参考文献
[1] 陈杰。本地文件系统数据更新模式研究[D].华中科技大学2018(14):240-241.
[2]刘洋。层次混合存储系统中缓存和预取技术研究[D].华中科技大学2019(14):246-247.

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值