全国疫情数据分析及可视化
一.问题描述与需求分析:
自2019年疫情伊始,我国便全力面对,建立了一套行之有效的应对机制,使得国内疫情迅速平息,然,此番疫情来势汹汹,席卷全球。在如今的后疫情时代,我们总体的疫情情况是什么样子,最近几天的疫情情况具体是什么样子,未来几天又是什么样子,人们的出行游玩情况,又是否受到了影响。
为了解决这些问题,我们需要对疫情发生的2020年各地人口机械增长数据,一定时间内各省新增确诊人数,无症状感染者,累计感染人数,治愈人数,死亡人数以及它们的比例和各省地图数据进行分析来确定。
二.项目流程
第一个部分,问题描述和需求分析,分析问题并确定需求的同时确定所需原始数据,,为了达成目的我们需要将哪些原始数据进行分析计算,并以此找出所需原始数据名称,如各地新增确诊人数,累计感染人数等。还进行具体人员责任分配和时间进度安排。
第二个部分,爬取所需数据,爬取了网站的疫情数据,获取了一定时间内各省新增确诊人数,无症状感染者,累计感染人数,治愈人数,死亡人数以及它们的比例和各省地图等原始数据。
第三个部分,代码的完成实现,首先将爬取的数据进行了持久化存储,然后,读取存储的数据,将全国现有确诊人数和新增确诊人数在各省的分布以地图的形式直观的表示出来,并将近十几天的中国疫情数据以折线图的形式展示出来,便于显示出近期疫情趋势,并利用这几天的数据,使用自回归模型进行拟合预测未来一天内疫情数据的变化,将各省的现有确诊人数和新增确诊人数进行降序排序,并绘制柱状图,直观的对比出各省的疫情情况。最后,获取了2020年全国各省疫情数据以及相关的人口流动数据,对两个数据进行了相关性的计算,并绘制了散点图表示出来,通过散点图可以发现这两个数据成正相关。
三.部分实现代码与截图:
import re import csv import json import requests import numpy as np import pandas as pd import matplotlib.pyplot as plt from pyecharts.charts import * from pyecharts import options as opts from statsmodels.tsa.ar_model import AutoReg #疫情数据的爬取 url='https://voice.baidu.com/act/newpneumonia/newpneumonia/?from=osari_aladin_banner'#指定url with open('data_1.csv', mode='a', encoding='utf-8', newline='') as f:#写入标题 csv_writer = csv.writer(f) csv_writer.writerow(['area', 'curConfirm', 'confirmedRelative']) headers={ 'user-agent':'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/84.0.4147.89 Safari/537.36 SLBrowser/7.0.0.12151 SLBChan/25', 'cookie':'PSTM=1633252280; BIDUPSID=22A143921F0C78830AE549B800962B6A; __yjs_duid=1_46ce603658406079ce2b7d5fa797d36a1633252284144; BDUSS=hXRFVrUjRpV1BjRDdmcGdyUWNnQ1doTEQzMjhhQ0hBOX5PbmtabG5FMElCRjFpRVFBQUFBJCQAAAAAAQAAAAEAAADOFQAYAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAh3NWIIdzViQj; BDUSS_BFESS=hXRFVrUjRpV1BjRDdmcGdyUWNnQ1doTEQzMjhhQ0hBOX5PbmtabG5FMElCRjFpRVFBQUFBJCQAAAAAAQAAAAEAAADOFQAYAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAh3NWIIdzViQj; BAIDUID=DE6D5B8C9A351F959EB01270B8141FE3:FG=1; lscaptain=srcactivitycaptainindexcss_91e010cf-srccommonlibsesljs_e3d2f596-srcactivitycaptainindexjs_a2e9c712; ZFY=j2rNtqhFLjvbe3pUzrUZtKXKCzLo81I5vBSsTzCsro0:C; BAIDUID_BFESS=DE6D5B8C9A351F959EB01270B8141FE3:FG=1; BDORZ=FFFB88E999055A3F8A630C64834BD6D0; BDRCVFR[TVogQ1G2T-s]=-kY6jVJCv-DpykGIhR8mv3; delPer=0; PSINO=2; H_PS_PSSID=; BA_HECTOR=ah0ga48g8h018l0k2l2h6mbm1hhghrm16; Hm_lvt_68bd357b1731c0f15d8dbfef8c216d15=1662171562,1662301146,1662345918,1662535545; Hm_lpvt_68bd357b1731c0f15d8dbfef8c216d15=1662535545' }#UA伪装 response=requests.get(url=url,headers=headers)#获取响应 data_html=response.text#得到响应数据 json_str=re.findall('"component":\[(.*)\],',data_html)[0]#正则解析数据 print(json_str) json_dict=json.loads(json_str)#将字符串类型转换为字典类型 #获取地图相关数据 caseList=json_dict['caseList'] for case in caseList: area=case['area']#省份 curConfirm=case['curConfirm']#确诊人数 confirmedRelative=case['confirmedRelative']#新增人数 print(area,curConfirm,confirmedRelative) with open('data_1.csv',mode='a',encoding='utf-8',newline='') as f:#数据持久化存储 csv_writer=csv.writer(f) csv_writer.writerow([area,curConfirm,confirmedRelative]) #将data_1的数据按降序排序 shop_1=pd.read_csv('data_1.csv',index_col='area')#读取data_1数据 shop_1.sort_values(by='curConfirm',inplace=True,ascending=False)#将数据按现有确诊人数进行降序排序 shop_1.to_csv('data_1.1.csv',mode='a+')#将排序后的数据持久化存储 print("shop_1") print(shop_1) shop_2=pd.read_csv('data_1.csv',index_col='area')#读取data_1数据 shop_2.sort_values(by='confirmedRelative',inplace=True,ascending=False)#将数据按新增确诊人数进行降序排序 shop_2.to_csv('data_1.2.csv',mode='a+')#将排序后的数据持久化存储 print("shop_2") print(shop_2)

#获取折线图数据
#获取折线图数据 trend=json_dict['trend'] updateDate=trend['updateDate'] print(updateDate)#日期 with open('data_2.csv', mode='a', encoding='utf-8', newline='') as f:#数据持久化存储 csv_writer = csv.writer(f) csv_writer.writerow(updateDate) list_data=trend['list'] list_new_1=list_data[10] data_1=list_new_1['data'] print(data_1)#新增本土 list_new_2=list_data[12] data_2=list_new_2['data'] print(data_2)#新增本土无症状 with open('data_2.csv', mode='a', encoding='utf-8', newline='') as f:#数据持久化存储 csv_writer = csv.writer(f) csv_writer.writerow(data_1) csv_writer.writerow(data_2) #数据分析及可视化 df_1=pd.read_csv('data_1.csv',encoding='utf-8')#读取数据 print(df_1) tab=Tab()#按钮
#现有确诊地图绘制
china_map_1=( Map() .add('现有确诊',[list(i) for i in zip(df_1['area'].values.tolist(),df_1['curConfirm'].values.tolist())],'china')#添加相关数据 .set_global_opts( title_opts=opts.TitleOpts(title="各地区确诊人数"),#设置标题 visualmap_opts=opts.VisualMapOpts(max_=250,is_piecewise=True),#设置数据范围 ) ) tab.add(china_map_1,'现有确诊')#添加到按钮中
#新增确诊地图绘制
china_map_2=( Map() .add('新增确诊',[list(i) for i in zip(df_1['area'].values.tolist(),df_1['confirmedRelative'].values.tolist())],'china')#添加相关数据 .set_global_opts( title_opts=opts.TitleOpts(title="各地区确诊人数"),#设置标题 visualmap_opts=opts.VisualMapOpts(max_=100,is_piecewise=True),#设置数据范围 ) ) tab.add(china_map_2,'新增确诊')#添加到按钮中
#折线图绘制
china_line=( Line(init_opts=opts.InitOpts(width="1200px",height="600px"))#画一个折线图,并设置其大小 .add_xaxis(updateDate)#设置x轴数据 .add_yaxis(series_name='新增本土',y_axis=data_1,is_smooth=True,is_symbol_show=False,markpoint_opts=opts.MarkPointOpts( data=[ opts.MarkPointItem(type_="max", name="最大值"), opts.MarkPointItem(type_="min", name="最小值")]))#设置y轴数据 .add_yaxis(series_name='新增本土无症状',y_axis=data_2,is_smooth=True,is_symbol_show=False,markpoint_opts=opts.MarkPointOpts( data=[ opts.MarkPointItem(type_="max", name="最大值"), opts.MarkPointItem(type_="min", name="最小值")]))#设置y轴数据 .set_global_opts( xaxis_opts=opts.AxisOpts( name='日期',#设置x坐标轴名称 name_textstyle_opts=opts.TextStyleOpts(font_size=20),#设置x坐标轴名称字体大小 axislabel_opts=opts.LabelOpts(font_size=22)),#设置x轴坐标字体大小 yaxis_opts=opts.AxisOpts( name='人数',#设置y坐标轴名称 min_=0,#设置y轴起始点为0 name_textstyle_opts=opts.TextStyleOpts(font_size=20),#设置y坐标轴名称字体大小 axislabel_opts=opts.LabelOpts(font_size=22)),#设置y轴坐标字体大小 title_opts=opts.TitleOpts( title='新增本土趋势',#设置标题 title_textstyle_opts=opts.TextStyleOpts(font_size=25),#设置标题字体大小 pos_left='center'),#设置居中 legend_opts=opts.LegendOpts(pos_right='%10'),#图列放在整个图右侧十分之一的位置 tooltip_opts=opts.TooltipOpts(trigger="axis")#竖线提示信息 ) ) tab.add(china_line,'新增本土趋势')#添加到按钮中
#绘制柱状图
china_bar_1=( Bar(init_opts=opts.InitOpts(width="1200px",height="600px"))#画一个柱状图,并设置大小 .add_xaxis(shop_1.index.tolist())#添加x轴 .add_yaxis('现有确诊人数',shop_1["curConfirm"].tolist())#添加y轴 .set_global_opts( xaxis_opts=opts.AxisOpts( name='省份',#设置x坐标轴名称 name_textstyle_opts=opts.TextStyleOpts(font_size=20),#设置x坐标轴名称字体大小 axislabel_opts=opts.LabelOpts(font_size=15)),#设置x轴坐标字体大小 yaxis_opts=opts.AxisOpts( name='人数',#设置y坐标轴名称 min_=0,#设置y轴起始点为0 name_textstyle_opts=opts.TextStyleOpts(font_size=20),#设置y坐标轴名称字体大小 axislabel_opts=opts.LabelOpts(font_size=15)),#设置y轴坐标字体大小 title_opts=opts.TitleOpts( title="现有确诊分布",#标题 title_textstyle_opts=opts.TextStyleOpts(font_size=25),#设置标题字体大小 pos_left='center'),#设置居中 legend_opts=opts.LegendOpts(pos_right='%10'),#图列放在整个图右侧十分之一的位置 datazoom_opts=[opts.DataZoomOpts()]#可滑动 ) ) tab.add(china_bar_1,'现有确诊分布')#添加到按钮中
china_bar_2=( Bar(init_opts=opts.InitOpts(width="1200px",height="600px"))#画一个柱状图,并设置大小 .add_xaxis(shop_2.index.tolist())#添加x轴 .add_yaxis('新增确诊人数',shop_2["confirmedRelative"].tolist())#添加y轴 .set_global_opts( xaxis_opts=opts.AxisOpts( name='省份',#设置x坐标轴名称 name_textstyle_opts=opts.TextStyleOpts(font_size=20),#设置x坐标轴名称字体大小 axislabel_opts=opts.LabelOpts(font_size=15)),#设置x轴坐标字体大小 yaxis_opts=opts.AxisOpts( name='人数',#设置y坐标轴名称 min_=0,#设置y轴起始点为0 name_textstyle_opts=opts.TextStyleOpts(font_size=20),#设置y坐标轴名称字体大小 axislabel_opts=opts.LabelOpts(font_size=15)),#设置y轴坐标字体大小 title_opts=opts.TitleOpts( title="新增确诊分布",#标题 title_textstyle_opts=opts.TextStyleOpts(font_size=25),#设置标题字体大小 pos_left='center'),#设置居中 legend_opts=opts.LegendOpts(pos_right='%10'),#图列放在整个图右侧十分之一的位置 datazoom_opts=[opts.DataZoomOpts()]#可滑动 ) ) tab.add(china_bar_2,'新增确诊分布')#添加到按钮中
#相关性
data_a = pd.read_excel("相关性数据.xlsx",usecols=[3],names=None) df_a=data_a.values.tolist() a=[] for li in df_a: a.append(li[0]) print(a) data_b = pd.read_excel("相关性数据.xlsx",usecols=[6],names=None) df_b=data_b.values.tolist() b=[] for li in df_b: b.append(li[0]) print(b) ab=np.array([a,b])#先构造一个矩阵 dfab=pd.DataFrame(ab.T,columns=['A','B'])#使用DataFrame作为数据结构,为方便计算,我们会将ab矩阵转置 pd_cov_a_b=dfab.A.cov(dfab.B)#计算ab的协方差 pd_corr_a_b=dfab.A.corr(dfab.B)#计算ab的相关系数 print('ab的协方差:') print(pd_cov_a_b) print('ab的相关系数:') print(pd_corr_a_b)
#散点图
scatter = ( Scatter(init_opts=opts.InitOpts(width="1200px", height="600px")) .add_xaxis(a) .add_yaxis("",b,symbol_size=20) .set_series_opts( label_opts=opts.LabelOpts(is_show=False) ) .set_global_opts( tooltip_opts=opts.TooltipOpts(is_show=False), xaxis_opts=opts.AxisOpts( type_="value", splitline_opts=opts.SplitLineOpts(is_show=True) ), yaxis_opts=opts.AxisOpts( type_="value", splitline_opts=opts.SplitLineOpts(is_show=True), axistick_opts=opts.AxisTickOpts(is_show=True) ) ) ) tab.add(scatter,'相关系数散点图')#添加到按钮中
#回归预测
tab.render('demo.html')#展示图片 #自回归预测 model=AutoReg(data_1,lags=3) results_AR=model.fit() plt.figure(figsize=(10,4)) plt.plot(data_1,'b',label='close') plt.plot(results_AR.fittedvalues,'r',label='AR_model') plt.legend() #print(len(results_AR.roots)) yhat = results_AR.predict(len(data_1), len(data_1)) print(yhat) plt.show()
#整合图表
#整合图表 page=Page(layout=Page.DraggablePageLayout) page.add( china_map_1, china_map_2, china_line, china_bar_1, china_bar_2, scatter ) page.render("all_demo.html")
四.总结与体会
首先,爬取数据的时候,不能正确定位数据的位置。
其次,获取数据的数据类型与所调用函数的数据类型不匹配。
通过对这些问题的解决与学习,我们对python有了更深刻的理解,同时现在的疫情还是很严峻,在做课设时咱们这里也成了高风险区,让我们感受到了python与现实生活的联系是如此之近,越是在这时候我们越要团结一心坚持到底,心往一处想劲往一处使,疫情定会被打败。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了