美国新冠肺炎疫情数据分析

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

文章目录

  • 使用python和spark对2020年美国新冠肺炎疫情数据分析
  • 前言
  • 一、实验环境
  • 二、数据集
    • 1.数据集下载
    • 2.格式转换
    • 3.将文件上传至HDFS文件系统中
  • 三、使用Spark对数据进行分析
    • 第一步,读取csv数据集文件
    • 第二步:引用相关数据包
    • 第三步:自编写RDD程序,主程序
    • 第四步:注意RDD读取路径为HDFS文件上传路径
    • 第五步:输出文件为result*.json(*为数字)
    • 第六步:查看文件是否输出成功
    • 第七步:创建本地文件夹,转化文件格式
  • 四、数据进行可视化
    • 第一步:安装pyecharts:pip install pyecharts
    • 第二步:编写可视化代码
    • 效果图
  • 五、总结


前言

提示:这里可以添加本文要记录的大概内容:
本案例以2020年美国新冠肺炎疫情数据作为数据集,以Python为编程语言,使用Spark对数据进行分析,并对分析结果进行可视化。


一、实验环境

(1)Linux: Ubuntu 16.04
(2)Hadoop3.1.3
(3)Python: 3.6
(4)Spark: 2.4.0
(5)Jupyter Notebook

二、数据集

1.数据集下载

本次作业使用的数据集来自数据网站Kaggle的美国新冠肺炎疫情数据集(从百度网盘下载,提取码:t7tu),该数据集以数据表us-counties.csv组织,其中包含了美国发现首例新冠肺炎确诊病例至今(2020-05-19)的相关数据。数据包含以下字段:
字段名称 字段含义 例子
date 日期 2020/1/21;2020/1/22;etc
county 区县(州的下一级单位) Snohomish;
state 州 Washington
cases 截止该日期该区县的累计确诊人数 1,2,3…
deaths 截止该日期该区县的累计确诊人数 1,2,3…

美国新冠肺炎疫情数据分析_第1张图片

2.格式转换

原始数据集是以.csv文件组织的,为了方便spark读取生成RDD或者DataFrame,首先将us-counties.csv转换为.txt格式文件us-counties.txt。转换操作使用python实现,代码组织在toTxt.py中,代码如下(示例):

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'))

运行结果如下:


美国新冠肺炎疫情数据分析_第2张图片

3.将文件上传至HDFS文件系统中

首先开启HDFS服务,再将文件上传至HDFS文件系统中,代码如下:

./bin/hdfs dfs -put /home/hadoop/us-counties.txt /user/hadoop

在这里插入图片描述
在这里插入图片描述
(上传路径是个已存在文件夹,若无该文件夹,先创建再进行上述操作)要使用 HDFS,首先需要在 HDFS 中创建用户目录:./bin/hdfs dfs -mkdir -p /user/yxm
在上传文件至HDFS文件系统:./bin/hdfs dfs -pu /home/yxm/us-counties.txt /user/yxm

在这里插入图片描述

在这里插入图片描述

出现以下信息即成功

在这里插入图片描述
可以查看文件夹是否存在:./bin/hdfs dfs -ls /user/yxm

出现下列信息即为成功

美国新冠肺炎疫情数据分析_第3张图片

三、使用Spark对数据进行分析

这里采用Python作为编程语言。


在对数据进行分析要有几个注意点,jupyter notebook的正常运行,使用Jupyter Notebook调试PySpark程序,以及python版本是否兼容。
本实验用的python是3.6.9,3.7无法正常进行实验。
调试jupyter notebook如下:

美国新冠肺炎疫情数据分析_第4张图片
输出正常
代码:

from pyspark import SparkConf, SparkContext
conf = SparkConf().setMaster("local").setAppName("My App")
sc = SparkContext(conf = conf)
logFile = "file:///usr/local/spark/README.md"
logData = sc.textFile(logFile, 2).cache()
numAs = logData.filter(lambda line: 'a' in line).count()
numBs = logData.filter(lambda line: 'b' in line).count()
print('Lines with a: %s, Lines with b: %s' % (numAs, numBs))

此处有两种方式进行数据分析,第一种是在jupyter notebook中运行,第二种是生成创建.py文件,用python环境运行。下面用的是第一种方法。

第一步,读取csv数据集文件

美国新冠肺炎疫情数据分析_第5张图片

第二步:引用相关数据包

在这里插入图片描述
代码:

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

第三步:自编写RDD程序,主程序

美国新冠肺炎疫情数据分析_第6张图片
代码:

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

第四步:注意RDD读取路径为HDFS文件上传路径

此处的路径与~/.bashrc当中的环境变量有关
美国新冠肺炎疫情数据分析_第7张图片
代码:

#主程序:
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")

第五步:输出文件为result*.json(*为数字)

美国新冠肺炎疫情数据分析_第8张图片
以此类推
美国新冠肺炎疫情数据分析_第9张图片

代码:


#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.计算每日较昨日的新增确诊病例数和死亡病例数
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日 美国各州的累计确诊人数和死亡人数
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.找出美国确诊最多的10个州
df4 = spark.sql("select date,state,totalCases from eachStateInfo  order by totalCases desc limit 10")
df4.repartition(1).write.json("result4.json")

#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.找出美国确诊最少的10个州
df6 = spark.sql("select date,state,totalCases from eachStateInfo  order by totalCases asc limit 10")
df6.repartition(1).write.json("result6.json")

#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全美和各州的病死率
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")

第六步:查看文件是否输出成功

查看HDFS上传文件下的目录:./bin/hdfs dfs -ls /user/yxm
美国新冠肺炎疫情数据分析_第10张图片
成功输出

第七步:创建本地文件夹,转化文件格式

在这里插入图片描述

若不提前创建文件夹,报错。
将HDFS上结果文件转储到本地文件系统中:


./bin/hdfs dfs -get /user/yxm/result1.json/part-00000.json /home/yxm/result/result1

美国新冠肺炎疫情数据分析_第11张图片
美国新冠肺炎疫情数据分析_第12张图片

提示输出成功,查看文件

在这里插入图片描述

四、数据进行可视化

第一步:安装pyecharts:pip install pyecharts

选择使用python第三方库pyecharts作为可视化工具。
在使用前,需要安装pyecharts,安装代码如下:

pip install pyecharts

美国新冠肺炎疫情数据分析_第13张图片

第二步:编写可视化代码

打开jupyter notebook,导入数据包
美国新冠肺炎疫情数据分析_第14张图片

编写程序,根据数据类型编写不同视图
文件输出路径为本地.josn文件路径

双柱状图:

美国新冠肺炎疫情数据分析_第15张图片

折线图:

美国新冠肺炎疫情数据分析_第16张图片
美国新冠肺炎疫情数据分析_第17张图片
美国新冠肺炎疫情数据分析_第18张图片

表格:

美国新冠肺炎疫情数据分析_第19张图片

词云图:

美国新冠肺炎疫情数据分析_第20张图片

象柱状图:

美国新冠肺炎疫情数据分析_第21张图片

词云图:

美国新冠肺炎疫情数据分析_第22张图片
美国新冠肺炎疫情数据分析_第23张图片

饼状图:

美国新冠肺炎疫情数据分析_第24张图片
在这里插入图片描述

查看输出文件:

在这里插入图片描述

效果图

美国新冠肺炎疫情数据分析_第25张图片
美国新冠肺炎疫情数据分析_第26张图片
美国新冠肺炎疫情数据分析_第27张图片
美国新冠肺炎疫情数据分析_第28张图片
美国新冠肺炎疫情数据分析_第29张图片
美国新冠肺炎疫情数据分析_第30张图片
美国新冠肺炎疫情数据分析_第31张图片
美国新冠肺炎疫情数据分析_第32张图片
美国新冠肺炎疫情数据分析_第33张图片
美国新冠肺炎疫情数据分析_第34张图片
美国新冠肺炎疫情数据分析_第35张图片

具体可视化实现代码如下:

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.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.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.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.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.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.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.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.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

五、总结

        通过本次实验,我们把在这一学期学的内容都使用了一遍,并且进行了融会贯通,本学期中,我们主要是对之前所学的python的内容进行巩固练习,并且对于一些细节处的修改;然后学习了shark,RDD,最后学了dataframe以及彼此之间的数据转换。
        在本次实验中,先是将数据集.csv文件进行格式转换,方便spark读取生成RDD或者DataFrame;接着将数据集上次到HDFS文件系统中,在这里我们要注意上传路径是个已存在文件夹,若无该文件夹,先创建再进行上述操作,否则可能会报错;接着使用spark对数据进行分析,并将分析结果输出,注意输出路径;记得HDFS查看文件是否输出成功;最后进行数据的可视化,在此需要安装可视化工具pyecharts对分析完成的数据进行可视化即可。
        本次实验中,我遇到过许多的问题,其中困扰我最久的是环境的搭建,python、hadoop、pyspark、pyecharts和Jupyter Notebook的安装,单个实现不难,主要是有一些彼此之间不兼容,版本或高或低,导致代码无法实现,重新安装时总会出现各种各样的问题。对此,我只能百度一一解决;然后就是数据可视化,由于对这一方面不太熟悉,因此在实现的过程中比较艰难,但好在一一克服了。
        通过了本次实验收获了良多,虽然在这个过程中经历了许多坎坷,但也认识到了自己的不足,找到了接下来努力的方向,进一步努力提升自己的技术水平。

[1] http://dblab.xmu.edu.cn/blog/2636-2/
注:参考厦门大学大数据实验室

你可能感兴趣的:(美国新冠肺炎疫情数据分析)