[COVID-19疫情] 三、通过Pandas进行初步分析

思来想去,经过一段时间的学习以及在相关老师的帮助下,开始准备专门写了一个Python大数据分析系列的博客,包括网络爬虫、可视化分析等。希望该系列能够对您有所帮助,同时也希望早日战胜病毒,武汉加油、湖北加油、全国加油。
致敬英雄,缅怀同胞
愿 花飨逝者 春暖斯人 山河无恙 世间皆安

前文分享了我国及世界范围内的疫情数据实时抓取。这篇文章通过Pandas对疫情进行初步的探索性分析。希望这篇可视化分析文章对您有所帮助,也非常感谢各位老师的无私分享,一起加油,战胜疫情!如果您有好的建议,希望能给作者留言呀!
1
2
5
6


同时推荐前面作者另外两个系列文章:

前文阅读:
[COVID-19疫情] 一、通过requests库等爬取当日疫情数据(实时)
[COVID-19疫情] 二、通过requests库等爬取历史总数据


一、数据和Pandas工具介绍

在上两篇博文中我们基于网易实时疫情播报平台,使用Python对疫情数据进行了爬取。本篇博文的案例主要内容是基于疫情数据的初步分析。这些数据我国各省和世界各国的实时数据及历史数据。
Pandas是基于NumPy数组构建的,能够灵活处理关系型数据,可便捷的完成索引、切片、组合以及选取数据子集等操作。接下来就让我们一起使用Pandas对疫情数据进行探索性分析。

针对有个别同学英语不好的,专门做了对比表:

列名 中文名称
date 日期
name 名称
id 编号
lastUpdateTime 更新日期
today_confirm 当日新增确诊
today_suspect 当日新增疑似
today_heal 当日新增治愈
today_dead 当日新增死亡
today_severe 当日新增重症
today_storeConfirm 当日现存确诊
total_confirm 累计确诊
total_suspect 累计疑似
total_heal 累计治愈
total_dead 累计死亡
total_severe 累计重症

二、实时数据分析

1、世界各国实时数据分析

1、首先读入数据,把列名改成中文。接着查看数据的基本信息并进行缺失值处理。

import pandas as pd

# 读取数据
today_word = pd.read_csv("./today_world_2020_03_27.csv")
# 查看世界各国实时数据
today_word.head()

7

2、下面我们来吧标题给换成中文的,首先创建个列表,然后使用rename()函数修改列名

name_dict = {'date':'日期','name':'名称','id':'编号','lastUpdateTime':'更新时间',
             'today_confirm':'当日新增确诊','today_suspect':'当日新增疑似',
             'today_heal':'当日新增治愈','today_dead':'当日新增死亡',
             'today_severe':'当日新增重症','today_storeConfirm':'当日现存确诊',
             'total_confirm':'累计确诊','total_suspect':'累计疑似',
             'total_heal':'累计治愈','total_dead':'累计死亡','total_severe':'累计重症'}

# 更改列名
today_world.rename(columns=name_dict,inplace=True)    # inplace参数判断是否在原数据上进行修改

today_world.head(3)

8

3、当拿到一份数据时,我们首先要观察数据的基本信息和特征的统计信息。这是我们可以分别用info()查看数据的基本信息,用describe()查看数据的统计信息。

基本信息
today_world.info()
9
统计信息
today_world.describe()
10

4、通过数据沃我们看到新增确诊、死亡等存在大量缺失值。为了便于观察,我们可以使用isnull()函数查看缺失值,并使用sum()函数计算缺失值比例。

# 计算缺失值比例
today_world_nan = today_world.isnull().sum()/len(today_world)

# 转变为百分数
today_world_nan.apply(lambda x: format(x, '.1%')) 

11

  • 根据上图我们发现当日新增相关数据缺失值较多,这是因为采集数据的当天的一些国家没有来得及更新数据,因此这些我们可以将其抛弃。
  • 当日现存确诊一列虽然为空,但是这个缺失值我们可以通过现有数据进行计算,公式为:
  • 当日现存确诊=累计确诊−累计治愈−累计死亡
  • 除了上述的数据之外,病死率也是一个非常重要的特征,病死率能够反应疾病的严重程度和医疗水平。病死率的计算公式为:
  • 病死率=累计死亡÷累计确诊
# 缺失值处理
today_world['当日现存确诊'] = today_world['累计确诊']-today_world['累计治愈']-today_world['累计死亡']

# 计算病死率,且保留两位小数
today_world['病死率'] = (today_world['累计死亡']/today_world['累计确诊']).apply(lambda x: format(x, '.2f')) 

# 将病死率数据类型转换为float
today_world['病死率'] = today_world['病死率'].astype('float')

# 根据病死率降序排序
today_world.sort_values('病死率',ascending=False,inplace=True)

# 显示病死率前十国家
today_world.head(10)

12

  • 根据上图我们看到排名第一的国家冈比亚病死率高达0.33,但从表中可知,该国累计确诊人数才3例。由此可知,病死率应该结合累计确诊人数一起查看。

5、为了方便查询特定的国家的数据,我们可以使用set_index()函数将国家设置为索引:

# 将国家名称设为索引
today_world.set_index('名称',inplace=True)

today_world.head(5)

13

这时,如果我们想查看各国的数据的化,可以直接通过传入列表获取多个国家的数据

today_word.loc['中国']
14

6、当前累计确诊人数top10国家,我们可以通过使用sort_values()含数据根据累计确诊人数进行排序

# 查看当前累计确诊人数前十国家
world_top10 = today_word.sort_values(['累计确诊'],ascending=False)[:10]

world_top10 = world_top10[['累计确诊','累计死亡','病死率']]

world_top10

15

但是这样并不直观,这是我们需要借助可视化进行分析:

# 导入matplotlib
import matplotlib.pyplot as plt

plt.rcParams['font.sans-serif']=['SimHei']    #正常显示中文
plt.rcParams['figure.dpi'] = 120      #设置所有图片的清晰度

# 绘制条形图
world_top10.sort_values('累计确诊').plot.barh(subplots=True,layout=(1,3),sharex=False,
                                             figsize=(7,4),legend=False,sharey=True)

plt.tight_layout()   #调整子图间距
plt.show()

16

  • 由图可知,目前美国累计确诊病例已远远高于其他国家,中国、意大利、西班牙人数也相对较高。而在病死率的图表上意大利则位列第一,可见疫情的严重性,西班牙、伊朗、法国、英国病死率紧跟其后。然而,累计确诊人数最高的美国病死率却相对较低,其中一个原因就是美国的医疗资源丰富,下图是一张每十万人ICU病床数量的国家排名条形图:

17

  • 我们可以看到,相比于其他国家,美国的医疗资源相当之丰富,紧随其后的德国也是如此,,这也是这次疫情病死率相比其他国家低的原因。

2、全国各省实时数据分析

各省的数据这些可以通过同世界各国数据分析一样,先进性数据清洗,然后分别探索全国新增确诊top10和全国现存确诊人数top10的地区。具体过程如下:

# 1
# 读取数据
today_province = pd.read_csv("./input/today_province_2020_03_31.csv")

# 创建中文列名字典
name_dict = {'date':'日期','name':'名称','id':'编号','lastUpdateTime':'更新时间',
             'today_confirm':'当日新增确诊','today_suspect':'当日新增疑似',
             'today_heal':'当日新增治愈','today_dead':'当日新增死亡',
             'today_severe':'当日新增重症','today_storeConfirm':'当日现存确诊',
             'total_confirm':'累计确诊','total_suspect':'累计疑似',
             'total_heal':'累计治愈','total_dead':'累计死亡','total_severe':'累计重症'}

# 更改列名
today_province.rename(columns=name_dict,inplace=True)    # inplace参数是否在原对象基础上进行修改

today_province.head()

# 2
# 查看数据基本信息
today_province.info()

# 3
# 查看数值型特征的统计量
today_province.describe()

# 4
# 计算各省当日现存确诊人数
today_province['当日现存确诊'] = today_province['累计确诊']-today_province['累计治愈']-today_province['累计死亡']

# 将各省名称设置为索引
today_province.set_index('名称',inplace=True)

today_province.info()

# 5
# 查看全国新增确诊top10的地区
new_top10 = today_province['当日新增确诊'].sort_values(ascending=False)[:10]

new_top10

1、全国新增确诊top10地区

# 查看全国新增确诊top10的地区
new_top10 = today_province['当日新增确诊'].sort_values(ascending=False)[:10]

new_top10

18

# 绘制条形图和饼图
fig,ax = plt.subplots(1,2,figsize=(10,5))

new_top10.sort_values(ascending=True).plot.barh(fontsize=10,ax=ax[0])
new_top10.plot.pie(autopct='%.1f%%',fontsize=10,ax=ax[1])

plt.ylabel('')
plt.title('全国新增确诊top10地区',size=15)
plt.show()

19

  • 从图中可知,香港、上海新增确诊人数最多,且在新增确诊前十名的地区,香港占比将近一半。

全国现存确诊人数top10的地区

# 查看全国现存确诊人数top10的省市
store_top10 = today_province['当日现存确诊'].sort_values(ascending=False)[:10]

store_top10

20

# 绘制条形图

store_top10.sort_values(ascending=True).plot.barh(fontsize=10)

plt.title('全国现存确诊top10地区',size=20)
plt.show()

21

  • 虽然湖北现存确诊人数仍位居第一,但已鲜有新增确诊病例。

三、历史数据分析

1、全国历史数据分析

全国历史数据是时间序列的数据类型,在数据清洗的时候需要对时间进行处理。此部分我们采用折线图来表示全国历史数据,并以此为基础分析全国新增确诊人数的变化趋势。
1、首先,我们还是要先读取数据,并且更改列名

# 读取数据
alltime_china = pd.read_csv("./alltime_China_2020_03_27.csv")

# 创建中文列名字典
name_dict = {'date':'日期','name':'名称','id':'编号','lastUpdateTime':'更新时间',
             'today_confirm':'当日新增确诊','today_suspect':'当日新增疑似',
             'today_heal':'当日新增治愈','today_dead':'当日新增死亡',
             'today_severe':'当日新增重症','today_storeConfirm':'当日现存确诊',
             'total_confirm':'累计确诊','total_suspect':'累计疑似',
             'total_heal':'累计治愈','total_dead':'累计死亡','total_severe':'累计重症'}

# 更改列名
alltime_china.rename(columns=name_dict,inplace=True)

alltime_china.head()

22

2、接下来我们进行缺失值处理

# 缺失值处理

# 计算当日现存确诊人数
alltime_china['当日现存确诊'] = alltime_china['累计确诊']-alltime_china['累计治愈']-alltime_china['累计死亡']

# 删除更新时间一列
alltime_china.drop(['更新时间','当日新增重症'],axis=1,inplace=True)

alltime_china.info()

23

3、与实时数据相比,历史数据的日期一列是非常重要的。我们通过使用pd.to_datatime()将日期的数据类型设为datetime,并将其设置为行索引,并随机选取数据。

# 将日期改成datetime格式
alltime_china['日期'] = pd.to_datetime(alltime_china['日期'])

# 设置日期为索引
alltime_china.set_index('日期',inplace=True)     
# 也可使用pd.read_csv("./input/alltime_China_2020_03_27.csv",parse_dates=['date'],index_col='date')

# 举例
alltime_china.loc['2020-01']

24

4、在数据清洗之后,我们可以通过绘制折线图查看疫情数据的变化趋势

# 时间序列数据绘制折线图
import matplotlib.pyplot as plt
import matplotlib.dates as dates
import matplotlib.ticker as ticker
import datetime

fig, ax = plt.subplots(figsize=(8,4))

alltime_china.plot(marker='o',ms=2,lw=1,ax=ax)

ax.xaxis.set_major_locator(dates.MonthLocator())    #设置间距
ax.xaxis.set_major_formatter(dates.DateFormatter('%b'))    #设置日期格式

fig.autofmt_xdate()    #自动调整日期倾斜

# 图例位置调整
plt.legend(bbox_to_anchor = [1,1])

plt.title('全国新冠肺炎数据折线图',size=15)
plt.ylabel('人数')
plt.grid(axis='y')
plt.box(False)
plt.show()

25

  • 由图可知,我国累计确诊人数在2月中旬已达到拐点,现存确诊人数也已从2月15日起逐步减少。同时,累计治愈人数稳步上升,且随现存确诊人数的下降而逐渐趋于平缓状态。

由于当日新增确诊病例数值较小,我们可以单独进行分析:

# 时间序列数据绘制折线图
fig, ax = plt.subplots(figsize=(8,4))

alltime_china['当日新增确诊'].plot(ax=ax, style='-',lw=1,color='c',marker='o',ms=3)

ax.xaxis.set_major_locator(dates.MonthLocator())    #设置间距
ax.xaxis.set_major_formatter(dates.DateFormatter('%b'))    #设置日期格式

fig.autofmt_xdate()    #自动调整日期倾斜

plt.title('全国新冠肺炎新增确诊病例折线图',size=15)
plt.ylabel('人数')
plt.grid(axis='y')
plt.box(False)
plt.show()

26

  • 我们可以看到2月12日新增病例达到峰值,这是为什么呢?这是因为评判标准的标准化所造成的。

2、世界各国历史数据分析

前面的一些预处理与前面相同:

# 1
# 读取数据
alltime_world = pd.read_csv("./alltime_world_2020_03_27.csv")

# 创建中文列名字典
name_dict = {'date':'日期','name':'名称','id':'编号','lastUpdateTime':'更新时间',
             'today_confirm':'当日新增确诊','today_suspect':'当日新增疑似',
             'today_heal':'当日新增治愈','today_dead':'当日新增死亡',
             'today_severe':'当日新增重症','today_storeConfirm':'当日现存确诊',
             'total_confirm':'累计确诊','total_suspect':'累计疑似',
             'total_heal':'累计治愈','total_dead':'累计死亡','total_severe':'累计重症'}

# 更改列名
alltime_world.rename(columns=name_dict,inplace=True)

alltime_world.head()

# 2
# 查看数据基本信息
alltime_world.info()

# 3
# 将日期一列数据类型变为datetime
alltime_world['日期'] = pd.to_datetime(alltime_world['日期'])

# 计算当日现存确诊
alltime_world['当日现存确诊'] = alltime_world['累计确诊']-alltime_world['累计治愈']-alltime_world['累计死亡']

alltime_world.info()


2、如果想要查看数据表中总共有哪些国家,我们可以使用unique()查看数据中的唯一值
# 查看唯一值,可使用len()查看个数 alltime_world['名称'].unique()

27

3、如果想查看每天给个国家出现新冠肺炎疫情,我们可以通过value_counts()函数帮助我们查看每一天的记录。
28

  • 图中显示3月22日就已经有129个国家出现疫情了

由于数据我们是26号爬取的数据,数据不完全,我们可以删除掉那一天

# 设置日期索引
alltime_world.set_index('日期',inplace=True)

# 3月26日数据统计不完全,我们将其删除
alltime_world = alltime_world.loc[:'2020-03-26']

如果想提取多个国家的数据,我们需要把国家那一列也设置成索引,这是可以通过groupby()函数将数据转换为层次化索引。

# groupby创建层次化索引
data = alltime_world.groupby(['日期','名称']).mean()

data.head()

29

想要提取部分数据,同样可以使用.loc方法,需先通过.loc(axis=)指定对行索引还是对列索引进行操作。比如,我们想提取中国、韩国、美国、意大利、英国、西班牙、德国的数据

# 提取部分数据
data_part = data.loc(axis=0)[:,['中国','日本','韩国','美国','意大利','英国','西班牙','德国']]

data_part.head()

30

如果想还原多级索引,我们可以使用reset_index()函数

# 将层级索引还原
data_part.reset_index('名称',inplace=True)

data_part.head()

31

绘制多个国家的累计确诊人数折线图

# 绘制多个国家的累计确诊人数折线图
fig, ax = plt.subplots(figsize=(8,4))

data_part['2020-02':].groupby('名称')['累计确诊'].plot(legend=True,marker='o',ms=3,lw=1)

ax.xaxis.set_major_locator(dates.MonthLocator())    #设置间距
ax.xaxis.set_major_formatter(dates.DateFormatter('%b'))    #设置日期格式

fig.autofmt_xdate()    #自动调整日期倾斜

plt.title('各国新冠肺炎累计确诊病例折线图',size=15)
plt.ylabel('人数')
plt.grid(axis='y')
plt.box(False)
plt.legend(bbox_to_anchor = [1,1])
plt.show()

32

  • 由图可知,中韩两国目前累计确诊人数已出现拐点,疫情趋于平稳,而美国在最近几天累计确诊人数呈现爆发性的增长,已位居世界第一。此外,意大利、西班牙两国增长速度也紧跟其后。

下面,我们再观察下各国新增确诊人数的变化情况

# 绘制各国新增确诊人数折线图
fig, ax = plt.subplots(figsize=(8,4))

data_part['2020-03':'2020-03-29'].groupby('名称')['当日新增确诊'].plot(legend=True,marker='o',ms=3,lw=1)

ax.xaxis.set_major_locator(dates.MonthLocator())    #设置间距
ax.xaxis.set_major_formatter(dates.DateFormatter('%b'))    #设置日期格式

fig.autofmt_xdate()    #自动调整日期倾斜

plt.title('各国新冠肺炎新增确诊病例折线图',size=15)
plt.ylabel('人数')
plt.grid(axis='y')
plt.box(False)
plt.legend(bbox_to_anchor = [1,1])
plt.show()

33

  • 各国新增确诊人数波动较大,但总体趋势呈上升状态。在3月下旬,美国和西班牙首次单日新增确诊人数破万,而最新数据显示美国单日新增已突破17000例。
  • 两张图对比,我们发现日本的数据较小,很难观察变化趋势,这是可以单独对日本进行绘制。
japan = alltime_world[alltime_world['名称']=='日本']

fig, ax = plt.subplots(figsize=(8,4))

japan['累计确诊'].plot(ax=ax, fontsize=10, style='-',lw=1,color='c',marker='o',ms=3,legend=True)
ax.set_ylabel('人数', fontsize=10)

ax1 = ax.twinx()
ax1.bar(japan.index, japan['当日新增确诊'])
ax1.xaxis.set_major_locator(dates.DayLocator(interval = 5))
ax1.xaxis.set_major_formatter(dates.DateFormatter('%b %d'))
ax1.legend(['当日新增确诊'],loc='upper left',bbox_to_anchor=(0.001, 0.9))
plt.grid(axis='y')
plt.box(False)
plt.title('日本新冠肺炎疫情折线图',size=15)

plt.show()

34

  • 我们发现日本前期新增确诊人数的变化几乎没有太大增幅,但在3月25日起,日本的新增确诊人数明显增大,同时累计确诊折线斜率也随之增加。

我又来要赞了,还是希望各位路过的朋友,如果觉得可以学到些什么的话,点个赞再走吧,欢迎各位路过的大佬评论,指正错误,也欢迎有问题的小伙伴评论留言,私信。每个小伙伴的关注都是本人更新博客的动力!!!

发布了38 篇原创文章 · 获赞 41 · 访问量 9700

猜你喜欢

转载自blog.csdn.net/qq_16146103/article/details/105332902