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

1、总体设计

1.1数据来源

本次作业使用的数据集来自数据网站Kaggle的美国新冠肺炎疫情数据集,该数据集以数据表us-counties.csv组织,其中包含了美国发现首例新冠肺炎确诊病例至2020-05-19的相关数据。该数据集以csv格式组织,各属性的含义如下:

字段名称

字段含义

例子

date

日期

2020/1/21;2020/1/22;

county

区县(州的下一级单位)

Snohomish;

state

Washington

cases

截止该日期该区县的累计确诊人数

1,2,3…

deaths

截止该日期该区县的累计死亡人数

1,2,3…

1.2实验环境

  1. Linux: Ubuntu 16.04
  2. Hadoop3.1.3
  3. Python: 3.6
  4. Spark: 2.4.0

1.3设计思路

1、原始数据集是以.csv文件组织的,为了方便spark读取生成RDD或者DataFrame,首先将csv转换为.txt格式文件。转换操作使用python实现。

2、将文件上传至HDFS文件系统中,路径为:“/user/hadoop/us-counties.txt”

3、采用编程方式读取us-counties.txt生成DataFrame。

4、使用Spark对数据进行分析。主要统计以下指标,所有结果保存为.json文件,分别是:

    1. 统计美国各州的累计确诊人数和死亡人数和病死率,并将 结果保存到Mysql数据库中。
    2. 统计美国确诊人数最多的十个州。
    3. 统计美国死亡人数最多的十个州。
    4. 统计美国确诊人数最少的十个州。

5、将Spark计算结果.json文件下载到本地文件夹。建议可对结果进行数据可视化。

1.4 实验流程图

 2、详细设计

2.1 格式转换

原始数据集是以.csv文件组织的,为了方便spark读取生成RDD或者DataFrame。转换操作使用python实现,代码写在在toTxt.py中,在当前环境下运行生成txt文件,具体代码如下:

import pandas as pd

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.2将文件上传至HDFS文件系统中

首先启动hadoop,伪分布式读取的 HDFS 上的数据,并查看启动结果,把本地文件系统的上传到HDFS文件系统中,具体路径是“/user/hadoop/us-counties.txt”。具体命令如下:

1.首先启动hadoop,并查看启动结果

cd /usr/local/hadoop

./sbin/start-dfs.sh

jps

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

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

2.3数据读取与DataFrame构建

首先读取数据文件,生成Spark DataFrame,使用的数据为结构化数据,因此可以使用spark读取源文件生成DataFrame以方便进行后续分析实现。首先导入第三方库,读取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")

2.4在MySQL中创建数据库和表

打开一个Linux终端,输入如下命令进入MySQL Shell环境,启动mysql,在MySQL Shell环境中,输入如下SQL语句创建数据库bigworkdata,创建表格。

service mysql start

mysql -u root -p

在MySQL Shell环境中,输入如下SQL语句创建数据库bigworkdata

mysql>create database bigworkdata;

使用如下SQL语句查看已经创建的所有数据库

mysql> SHOW DATABASES;

使用如下SQL语句打开数据库

mysql> USE bigworkdata;

使用如下SQL语句创建一个表usdata:

mysql>CREATE TABLE usdata(

    -> state char(50),

    -> cases int,

    -> deaths int,

-> deaths_rate double);

查看已经创建的表

mysql> SHOW TABLES;

2.5数据分析

1统计美国各州的累计确诊人数和死亡人数和病死率,并将结果保存到Mysql数据库中。首先筛选数据,然后以state作为分组字段,对cases和deaths字段进行汇总统计。因为病死率 = 死亡数/确诊数,对DataFrame注册临时表按公式计算。

#1.计算每日的累计确诊病例数和死亡数

df1 = 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")

df1.sort(df1["totalCases"].desc()).repartition(1).write.json("result1.json") #写入hdfs

#写入数据库

prop = {}

prop['user'] = 'root'

prop['password'] = '123456'

prop['driver'] = "com.mysql.jdbc.Driver"

df1.write.jdbc("jdbc:mysql://localhost:3306/bigworkdata",'eachStateInfo','append',prop)

#注册为临时表供下一步使用

df1.createOrReplaceTempView("eachStateInfo")

#5.统计美国及各州的病死率

df5 = 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()

df5.sort(df5["sign"].asc(),df5["deathRate"].desc()).repartition(1).write.json("result5.json")

2)统计美国确诊人数最多的十个州。

对注册临时表,然后按确诊人数降序排列,并取前10个州。

df2 = spark.sql("select date,state,totalCases from eachStateInfo  order by totalCases desc limit 10")

df2.repartition(1).write.json("result2.json")

3)统计美国死亡人数最多的十个州。

对注册临时表,然后按死亡人数降序排列,并取前10个州。

df3 = spark.sql("select date,state,totalDeaths from eachStateInfo  order by totalDeaths desc limit 10")

df3.repartition(1).write.json("result3.json")

4)统计美国确诊人数最少的十个州。

对注册临时表,然后按确诊人数升序排列,并取前10个州。

df4 = spark.sql("select date,state,totalCases from eachStateInfo  order by totalCases asc limit 10")

df4.repartition(1).write.json("result4.json")

2.6结果文件

将2.5中的Spark计算结果保存.json文件,方便后续可视化处理。由于使用Python读取HDFS文件系统不太方便,故将HDFS上结果文件转储到本地文件系统中,使用以下命:使用python第三方库pyecharts作为可视化工具安装pyecharts具体可视化实现代码组织与showdata.py文件中具体可视化实现代码如下:

./bin/hdfs dfs -get /user/hadoop/result1.json/*.json /home/hadoop/result/result1

./bin/hdfs dfs -get /user/hadoop/result2.json/*.json /home/hadoop/result/result2

./bin/hdfs dfs -get /user/hadoop/result3.json/*.json /home/hadoop/result/result3

./bin/hdfs dfs -get /user/hadoop/result4.json/*.json /home/hadoop/result/result4

./bin/hdfs dfs -get /user/hadoop/result5.json/*.json /home/hadoop/result/result5

2.7数据可视化

使用python第三方库pyecharts作为可视化工具,安装pyecharts具体可视化实现代码组织与showdata.py文件中,具体可视化实现代码如下:

pip install pyecharts

#导入第三方库

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"

    allState = []

    totalCases = []

    totalDeaths = []

    deathRate = []

    with open(root, 'r') as f:

        while True:

            line = f.readline()

            if not line:                            # 到 EOF,返回空字符串,则终止循环

                break

            js = json.loads(line)

            #row = []

            allState.append(str(js['state']))

            totalCases.append(int(js['totalCases']))

            totalDeaths.append(int(js['totalDeaths']))

            deathRate.append(float(js['deathRate']))

            #allState.append(row)

    table = Table()

    d = (

    Bar()

    .add_xaxis(allState)

    .add_yaxis("累计确诊人数", totalCases, stack="stack1")

    .add_yaxis("累计死亡人数", totalDeaths, stack="stack1")

    .add_yaxis("死亡率", deathRate, 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/result2.html")

    )

#2.画出美国确诊最多的10个州——>词云图

def drawChart_2(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/result2/result2.html")

    )

#3.画出美国死亡最多的10个州——>柱状图、象柱状图

def drawChart_3(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']))

d = (  # 柱状图

    Bar()

    .add_xaxis(state)

    .add_yaxis("累计死亡人数", totalDeath, stack="stack1")

    .set_series_opts(label_opts=opts.LabelOpts(is_show=False))

    .set_global_opts(title_opts=opts.TitleOpts(title="美国死亡最多的10个州"))

    .render("/home/hadoop/result/result3/result34.html")

)

    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/result3/result3.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 = (

    Funnel()

    .add("State",data,sort_="ascending",label_opts=opts.LabelOpts(position="inside"),)

    .set_global_opts(title_opts=opts.TitleOpts(title="美国各州确诊最少的10个州"))

    .render("/home/hadoop/result/result4/result4.html")

    )

#5.美国的病死率--->饼状图

def drawChart_5(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/result5/result5.html")

    )

#可视化主程序:

index = 1

while index<6:

    funcStr = "drawChart_" + str(index)

    eval(funcStr)(index)

    index+=1

程序运行结果测试与分析

格式转换

 

 

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

 

 数据读取与DataFrame构建

 在MySQL中创建数据库和表

 

 

 数据分析

 

 

 

 

 结果文件

 

 

 

 数据可视化

 

 

 

 

 

 

 

 

 

 

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值