一文教你动态展现全球疫情变化趋势
The following article is from Smart金科 Author 小艾
大家好,我是朱小五
本文用一个完整的案例,带大家掌握用pyecharts绘制动态变化图,不仅有pyecharts的绘制方法教程,还给大家展示了完整的数据清洗和数据处理流程,干货很多。
一:获取疫情数据
本文所采用的疫情数据,来自于github,下载地址见文末,大家可自行下载,首先,我们导入已下载好的全球疫情数据:
###常规导入pyecharts必备模块
from pyecharts import options as opts
from pyecharts.charts import Bar, Timeline
from pyecharts.faker import Faker
###导入json、pandas工具
import json
import pandas as pd
### 导入已经下载好的数据
with open("C://Users//Administrator//Desktop//DXYArea-TimeSeries.json.txt", "r", encoding="utf-8") as f: # 打开文件
data = f.read() # 读取文件
print(data)
### 将json文本导入,导入后转换为dict格式
res_dict = json.loads(data)
### dict格式数据入参,初始化DataFrame类
res_df = pd.DataFrame(res_dict)
这里有个初始化DataFrame的小trick,直接将dict格式的数据作为入参,可生成DataFrame格式,其中dict的key则成为了DataFrame中的column。
二:数据清洗及数据处理
一般我们所获取的原始数据,会有很多脏数据需要清洗,另外数据格式也需要进行处理,处理成绘图所需要的数据。
该数据为时间序列数据,第一步,我们先将原始数据的时间戳处理为标准的时间格式。
### 将时间戳进行标准化处理
import time
###构建时间标准化函数
def time_transform(timenum):
timetemp = float(timenum/1000)
### 全球时间统一
tuptime = time.localtime(timetemp)
### 转换为月日时间格式
standardtime = time.strftime("%m-%d", tuptime)
return standardtime
#### 循环处理每行的时间戳,注意DataFrame的索引方式
for i in range(len(res_df)):
res_df.iloc[i, 28] = time_transform(res_df.iloc[i, 28])
#### 展示下当前的时间序列
res_df1 = res_df
date = list(set(res_df1['updateTime']))
date.sort()
打印date,可看到该时间序列从1-22日开始,结束于4月5日,从疫情开始爆发到当前的数据均有覆盖。
第二步,我们再观察数据发现,在同一天内,某个城市会有多条数据,返回查看原始数据的更新方式,才发现,原始数据是通过爬虫的方式每天收集网络上公布的数据,因为公布数据的时间不固定,每日爬虫的更新频率也不固定,为了保证数据的实时性或准确性,每日会进行多次爬虫,每次爬虫都会向数据库写入一条数据,正因为如此,才有我们看到的,同一天内,同城市内会有多条数据。
了解数据逻辑后,我们直接上代码来处理:
### 建一个空的DataFrame,以备后续使用
temp_all = pd.DataFrame([])
### 循环对每日的数据进行处理
for i in date:
### 取出某日的所有数据,注意DataFrame条件筛选的写法
temp = res_df1[res_df1['updateTime'] == i]
#### DataFrame的去重,保留最后一行数据
temp = temp.drop_duplicates(["provinceName"], keep='last')
#### 将去重后的数据,重新添加到空的DataFrame
temp_all = temp_all.append(temp)
### 重置DataFrame的index
temp_all = temp_all.reset_index(drop=True)
这里要掌握DataFrame的去重写法,第一个参数为去重的基准列,keep参数为去重后保留行的准则。
第三步,我们再按照国家进行分组汇总统计,分组统计也是我们在数据分析中需要常用的方法,出现率非常高,大家一定重点掌握。
### 进行分组求和
countrydata = list()
### 仍然是按日期循环处理
for i in date:
temp = temp_all[temp_all['updateTime'] == i]
###利用groupby函数进行分组汇总
temp_group = temp.groupby("countryName")
###计算每一个分组的和
result = temp_group.sum()
### 取出求和后的三列数据(确诊数、死亡数、治愈数)
result_data = result[["confirmedCount", "deadCount", "curedCount"]]
result_data["countryName"] = list(result_data.index)
### 组合成时间序列数据
countrydata.append(result_data)
### 保留关注的国家
country = ["中国","韩国","日本","马来西亚","西班牙","葡萄牙","菲律宾","荷兰","英国","美国",
"瑞士","瑞典","法国","比利时","新加坡","挪威","意大利","德国","希腊",
"奥地利","伊朗","卡塔尔","加拿大","丹麦"]
for i, cdata in enumerate(countrydata):
### 取出关注国家的数据,如果没有数据,则填充为0
countrydata[i] = cdata.loc[country].fillna(0)
第四步,部分数据由于操作不当,可能会导致数据缺失,对于缺失的数据,在第三步,我们基本上都填充为0,但在这个场景,填充为0并不是一个最佳的选择,因为属于时间序列数据,后一天的数据一定会大于等于前一天的数据,基于这个数据特性,我们再一次对于为0的数据进行处理,将为0的数据替换为前一天不为0的数据,来看如下代码实现:
### 处理部分为0的数据
for i, cdata in enumerate(countrydata):
if i == 0:
continue
### 对于为0的数据进行替换,替换成前一天不为0的数据
for c in country:
c_current_data = cdata.loc[c]
c_last_data = countrydata[i-1].loc[c]
if c_current_data["confirmedCount"] == 0 and c_last_data["confirmedCount"] > 0:
cdata.loc[c, "confirmedCount"] = c_last_data["confirmedCount"]
if c_current_data["deadCount"] == 0 and c_last_data["deadCount"] > 0:
cdata.loc[c, "deadCount"] = c_last_data["deadCount"]
if c_current_data["curedCount"] == 0 and c_last_data["curedCount"] > 0:
cdata.loc[c, "curedCount"] = c_last_data["curedCount"]
三:pyecharts绘制动态图
经过上一步繁琐的数据清洗过程,数据基本上已经处理成了我们想要的标准格式,接下来就开始进行绘图了,这里绘制动态图我们用pyecharts模块,pyecharts模块基于百度开源的echarts,用于在python中绘制echarts图表,实战中出真知,接下来我们来看如何用pyecharts绘制随时间变化的动态图形。
由于本文的主题是绘制全球的数据变化趋势,因此在绘制之前,我们先将国内的数据进行剔除:
### 去掉中国的数据
country = country[1:]
new_countdata = []
for i in countrydata:
new_data = i.drop(index="中国")
new_countdata.append(new_data)
countrydata = new_countdata
接着在利用pyecharts的timeline模块,绘制动态变化图表:
###首先构造时间线图表对象
tl = Timeline()
###设置相关参数
'''
is_auto_play:自动播放
is_timeline_show:时间线是否展示
play_interval:播放时间间隔(ms)
is_loop_play:是否循环播放
'''
tl.add_schema(is_auto_play=True,is_timeline_show=False,play_interval=800,is_loop_play=False)
### 按照时间线,循环生成条形图
for i, idate in enumerate(date):
### 生成条形图
bar = (
Bar()
.add_xaxis(country) ## X轴
.add_yaxis("确诊人数", list(countrydata[i]["confirmedCount"]), label_opts=opts.LabelOpts(position="right"))
.add_yaxis("死亡人数", list(countrydata[i]["deadCount"]), label_opts=opts.LabelOpts(position="right"))
.reversal_axis()
.set_global_opts(
title_opts=opts.TitleOpts("全球疫情数据变化 (日期: {} )".format(idate)),
xaxis_opts=opts.AxisOpts(
type_="value",
min_="min",
max_="max")
)
)
### 将单日的条形图添加到时间线图表对象中
tl.add(bar, "{}".format(idate))
### 最后将时间线图表导入到html文件中,用浏览器打开即可看到随时间变化的动态图形
tl.render('C://Users//Administrator//Desktop//test1.html')
最后浏览器打开生成的html文件,图表样式如下,会自动随着时间的变化,展示数据变化趋势。够炫酷吧!快自己动手来构造一个属于你自己的动态变化图吧!
文中全球疫情数据
关注公众号「凹凸数据」后台回复“0407”即可获取
近期文章,点击图片即刻查看
后台回复「进群」,加入读者交流群~
点击「积分」,了解积分规则~