本文来源于和鲸社区,作者王大毛
文中涉及数据集下载地址:
https://www.kesci.com/home/project/5e426eb4b8c462002d69c1c9/dataset
导入库
导入数据
import pandas as pd
import matplotlib.pyplot as plt
import folium
import folium.plugins as plugins
import numpy as np
import datetimedata= pd.read_csv("/home/kesci/input/2019ncov5600/2019_nCoV_data.csv")
print(data.head())
print(data.info())
一、数据清洗
1.Sno
编号列没有用,要删去
data.drop(['Sno'],axis=1,inplace=True);
2.部分国家对应的地区为NAN
,需要填充为空白字符串
data['Province/State'].fillna('',inplace=True)
3.部分国家/地区,受感染人数为0,也被列在表格中,需要删去
data.drop(data[data['Confirmed']==0].index.to_list(),axis=0,inplace=True)
4.查看受影响的国家/地区的数量
countries = data['Country'].unique().tolist()
print(countries)
5.中国有China, Mainland China
两个写法,需要统一;另外还有一些你懂的问题需要修正
data['Country'].replace({'Mainland China':'China','Hong Kong':'China','Macau':'China','Taiwan':'China'},inplace=True)
countries = data[data['Confirmed']!=0]['Country'].unique().tolist()
print('迄今为止,受影响的国家/地区:',countries)
print('迄今为止,受影响的国家/地区个数:',len(countries))
二、取出最新数据
观察后发现,这个原始表格每天会把最新的数据更新在表格最后,而且,并不是每天每个国家都会更新数据。所以,需要筛选出每个国家的最新数据
5.将Date
转化为datetime格式,方便操作后面进行时间的比较
data['Date'] = data['Date'].apply(pd.to_datetime)
data.head()
6.按国家+城市字段分组,方便进行时间上的筛选
grouped = data.groupby(['Country','Province/State'])
7.选出每个国家/城市最新的数据
latest = grouped['Date'].idxmax()
data_latest = data.loc[latest]
data_latest.head()
又发现一个问题,比如Australia,一开始是以国家为单位报数据,之后又分成小区域报数据,会导致计算重复,所以要删除这部分数据。也不能直接删,因为不知道有多少国家的数据有这个问题。
8.筛选出国家对应的城市字符串为空,且该国家下的城市(包括空字符串)数量大于一 的数据
useless=data_latest[
(data_latest['Province/State']=='') &
(data_latest['Country'].apply(lambda x:data_latest['Country'].value_counts()[x])>1)
].index.to_list()
useless
9.删除这些数据
data_latest.drop(useless,inplace=True)
三、简单的可视化
10.查看各个国家总感染数据
world_cases = data_latest.groupby(['Country'])['Confirmed','Deaths','Recovered'].sum().sort_values(by='Confirmed', ascending=False)
world_cases
11.可视化以上数据,因为中国的确诊数量太大,故不放在图片里
plt.figure(figsize=(12, 8))
plt.barh(y=world_cases[1:].index,width=world_cases['Confirmed'][1:],color='lightcoral')
读入坐标数据
world_coordinates = pd.read_csv('/home/kesci/input/2019ncov5600/world_coordinates.csv')
12.将坐标数据与国家感染数据合并
world_data = pd.merge(world_coordinates,world_cases,on='Country').sort_values(by='Confirmed', ascending=False)
world_data
13.用folium创建一个初始地图,中心点(35,0),缩放2.3
world_map = folium.Map(location=[35, 0], zoom_start=2.3)
world_map
14.先尝试在地图上画出中国的点
lat=world_data.iloc[0]['latitude']
lon=world_data.iloc[0]['longitude']
folium.CircleMarker([lat, lon],
radius=20,
color='red',
fill_color='red',
fill_opacity=0.7,
popup = ('<strong>国家</strong>: China<br>'
'<strong>确诊</strong>: ' + str(world_data.iloc[0]['Confirmed']) + '<br>')
).add_to(world_map)
world_map
15.了解套路之后,用for
画出剩余的圆圈
for lat, lon, value, name in zip(
world_data.iloc[1:]['latitude'],
world_data.iloc[1:]['longitude'],
world_data.iloc[1:]['Confirmed'],
world_data.iloc[1:]['Country']):
folium.CircleMarker([lat, lon],
radius=value*0.2,
color='red',
fill_color='red',
popup = ('<strong>国家</strong>: ' + str(name).capitalize() + '<br>'
'<strong>确诊</strong>: ' + str(value) + '<br>')
).add_to(world_map)
world_map
16.查看中国的各地区的数据
china_cases=data_latest[data_latest['Country']=='China'].sort_values(by='Confirmed', ascending=False)
china_cases.head()
17.画出出湖北外确诊病例的饼图
explode =np.hstack((np.zeros(10),np.linspace(0,3,len(china_cases)-11)))
plt.figure(figsize=(12, 8))
plt.pie(china_cases['Confirmed'][1:],labels=china_cases['Province/State'][1:],autopct='%1.1f%%',explode=explode);
18.画出除湖北外确诊和痊愈的数据
plt.figure(figsize=(12, 8))
plt.barh(width="Confirmed", y="Province/State", data=china_cases[1:], color="lightcoral");
plt.barh(width="Recovered", y="Province/State", data=china_cases[1:], color="palegreen");
读取中国的坐标数据集
china_coordinates= pd.read_csv("/home/kesci/input/2019ncov5600/china_Province_coordinates.csv")
china_coordinates.head()
19.坐标数据集中,name3
要和Province/State
匹配,所以要改个名字。以及,原表格Province/State
有大写,要处理成全部小写
china_coordinates.rename(columns={'name3':'Province/State'},inplace=True)
china_cases['Province/State']=china_cases['Province/State'].map(lambda x:x.lower())
20.两个表格数据匹配
china_data = china_cases.merge(china_coordinates)
china_data.head()
21.画出中国的感染分布,先画一个背景,中心点(39.91666667,116.383333),基础缩放4
latitude = 39.91666667
longitude = 116.383333
china_map1 = folium.Map(location=[latitude, longitude], zoom_start=4)
china_map1
22.画出武汉的数据
folium.CircleMarker([china_data.iloc[0]['lat'],china_data.iloc[0]['lon']],
radius=20,
color='red',
fill_color='red',
fill_opacity=0.7,
popup = ('<strong>省份</strong>: 湖北<br>'
'<strong>确诊: </strong>' + str(china_data.iloc[0]['Confirmed']) + '<br>'),
).add_to(china_map1)
china_map1
23.画其他省市的数据
for lat, lon, value, name in zip(
china_data.iloc[1:]['lat'],
china_data.iloc[1:]['lon'],
china_data.iloc[1:]['Confirmed'],
china_data.iloc[1:]['name2']):
folium.CircleMarker([lat, lon],
radius=value*0.01,
color='red',
fill_color='red',
popup = ('<strong>国家</strong>: ' + str(name) + '<br>'
'<strong>确诊</strong>: ' + str(value) + '<br>')
).add_to(china_map1)
china_map1
四、复杂的可视化
这部分我们要做个动态的地图
先读取另一份颗粒度细一点儿的数据
china_history=pd.read_csv('/home/kesci/input/ncov6321/DXYArea.csv')
china_history.head()
24.再来一套和之前差不多的操作,丢掉province_confirmedCount, province_suspectedCount, province_curedCount, province_deadCount
四列数据
china_history.drop([
'province_confirmedCount',
'province_suspectedCount',
'province_curedCount',
'province_deadCount'],
axis=1,
inplace=True
)
25.将updateTime
转换成date格式,就是只保留日期部分
china_history['updateTime']=china_history['updateTime'].apply(pd.to_datetime).dt.date
因为涉及到后面要匹配城市名字和坐标数据集的问题,所以现在要分几部分修改一些城市(区域)的写法
26.因为大部分城市都没有加“市”字,所以,要把直辖市的下属区的“区”字去掉。另外,这几个直辖市有时加“区”有时不加,所以需要判定一下(以下就写了上海市的)
china_history.loc[china_history['provinceName'] == '上海市','cityName'] = china_history[china_history['provinceName'] == '上海市']['cityName'].apply(
lambda x: x[0:len(x)-1] if len(x)>2 else x)
还有一些没有变化规律的城市名字,互联网民工手动整理出来了,是个叫city_rename
的字典
city_rename= {
'恩施州':'恩施土家族苗族自治',
'神农架林区':'神农架林',
...
'丽江市':'丽江'}
27.这部分没有规律的名字也同样需要修改
china_history['cityName']=china_history['cityName'].apply(
lambda x:city_rename[x] if x in city_rename else x)
读入详细坐标数据集
china_coor2=pd.read_csv('/home/kesci/input/chinacoor9160/china_coordinates.csv',header=None)
china_coor2.head()
28.因为坐标集没带标题,所以要给标题重命名,顺便将城市名列改成和前面一致
china_coor2.rename(columns={0:'code',1:'cityName',2:'lon',3:'lat'},inplace=True)
29.因为前面感染数据的表格,城市名后面都没有带“市”“区”,所以统一给去掉
china_coor2['cityName']=china_coor2['cityName'].apply(lambda x:x[0:len(x)-1])
china_coor2.head()
30.2个表格合并
china_history_data=china_history.merge(china_coor2)
china_history_data.head()
这里开始做动态地图需要的数据。需要构造一个三维数组,形如[[[Y1,X1,W1],...,[Y1,X1,W1]],[[Y1,X1,W1],...,[Y1,X1,W1]],...,[[Y1,X1,W1],...,[Y1,X1,W1]]],最外面一层是时间,每一层时间里面包含一堆数据点,每个数据点里面是坐标+数值。
31.筛出时间帧
update_time=china_history_data['updateTime'].unique()
32.用for
循环构造出三维的数组
data_move=[]
for i in update_time[::-1]:
tmp_pd=china_history_data[china_history_data['updateTime']==i]
data_move.append(tmp_pd[['lat','lon','city_confirmedCount']].values.tolist())
33.再开个新地图,将刚刚构造的数组传给folium的HeatMapWithTime
,并设置auto_play=True
m=folium.Map(location=[latitude, longitude], zoom_start=4)
plugins.HeatMapWithTime(data_move[:15],auto_play=True).add_to(m)
m
往期精彩回顾
适合初学者入门人工智能的路线及资料下载机器学习在线手册深度学习在线手册AI基础下载(pdf更新到25集)本站qq群1003271085,加入微信群请回复“加群”获取一折本站知识星球优惠券,请回复“知识星球”喜欢文章,点个在看