新冠疫情本土病例分析挖掘
Github链接:https://github.com/LinShuu/102192104
PSP2.1 | Personal Software Process Stages | 预计耗时(分钟) | 实际耗时(分钟) |
---|---|---|---|
Planning | 计划 | 60 | 60 |
Estimate | 估计这个任务需要多少时间 | 30 | 30 |
Development | 开发 | 2880 | 2880 |
Analysis | 需求分析(包括学习新技术) | 2340 | 2000 |
Design Spec | 生成设计文档 | 30 | 30 |
Design Review | 设计复审 | 30 | 30 |
Coding Standard | 代码规范(为目前的开发制定合适的规范) | 30 | 30 |
Design | 具体设计 | 1440 | 1440 |
Coding | 具体编码 | 400 | 360 |
Code Review | 代码复审 | 30 | 20 |
Test | 测试(自我测试,修改代码,提交修改) | 720 | 60 |
Reporting | 报告 | 60 | 150 |
Test Repor | 测试报告 | 60 | 0 |
Size Measurement | 计算工作量 | 30 | 30 |
Postmortern & Process Improvement Plan | 事后总结,并提出过程改进计划 | 30 | 20 |
合计 | 8170 | 7140 |
-
技术栈:爬虫 + jupyter notebook + pyecharts
-
从阅读完题目到完成作业,这一次的任务被我拆成了三个环节。第一个环节是了解项目所用到的技术栈,我通过上网学习网课,查找资料等,学习python的基础语法,爬虫的使用及数据可视化常用的库;第二个环节是进行代码的编写,通过学习借鉴网上丰富的资源来进行项目代码的编写,通过百度等解决运行环境所遇到的问题;第三个环节是检查代码中的细节问题进行修改,并复习github上传代码相关知识,进行代码的上传等。
-
代码的业务逻辑主要分为以下几个部分:
-
1、发送请求,获取疫情首页
-
2、从疫情首页中提取疫情相关数据
-
3、创建工作表并将所需的疫情数据存入工作表中
-
-
在请求url数据时,为了解决反爬机制的问题,可以在请求中加上headers来解决
#为了避免反爬,伪装成浏览器 headers = {'user-agent' : 'Mozilla/5.0 (Windows NT 10.0; Win64; x64)\ AppleWebKit/537.36 (KHTML, like Gecko) Chrome/97.0.4692.71 Safari/537.36 Edg/97.0.1072.55'}
-
获取数据后,使用xpath解析数据,生成HTML对象
from lxml import etree html = etree.HTML(result) result = html.xpath('//script[@type="application/json"]/text()') result = result[0]
-
使用json.loads()方法可以将字符串转换为Python的基本数据类型
import json result = json.loads(result)
-
采集数据时,可加入进度数据条让用户界面看起来更加友好,特别是在数据量较大,所需读取时间较久的情况下,通过
from tqdm import tqdm
引入tqdm,在原先循环读取的基础上套接tqdm()即可。for each in tqdm(result,"采集数据"): relativeTime = int(each['relativeTime']) # 时间 content_time = time.strftime('%Y-%m-%d %H:%M', time.localtime(relativeTime)) list_name = [each["area"],content_time,each["confirmed"],\ each["died"],each["crued"],each["confirmedRelative"],each["asymptomaticLocalRelative"]]
-
数据保存,较为简单的是直接调用save方法保存,在参考网上资料后,我试用过"to_csv"、"to_excel"等方法,但是在编码方面总是会出问题,最后还是选择了用save。在数据量较大的情况下,将数据保存为.csv文件比xlsx要好。
wb.save('./data.xlsx')
抓取页面的近日值得关注的新闻信息,存入txt文件
with open("data.txt","w") as f:
for each in tqdm(message,"热点信息采集"):
hotspot = each["conf_data"]
if hotspot != None:
hotspot = hotspot["notices"][0]["title"]
f.write(hotspot + "\n")
-
主要思路是读取文件中的数据,通过pyecharts库在jupyter的环境下生成需要的柱状图、折线图等。Bar模块用来绘制柱状图,Line模块用来绘制折线图,Map模块则内置了很多的地图组件,来进行数据分布的显示。
-
在进行柱状图绘制的过程中,我遇到了横坐标显示过于拥挤导致部分数据重叠的问题。由于pyecharts中默认坐标标签重叠时将间隔显示,故还存在部分省份坐标信息不显示的问题。通过旋转横坐标标签的文字方向,我解决了标签重叠的问题,但是数据重叠问题依旧存在,最后通过初始化时增大柱状图尺寸并缩小字体字号来解决。代码如下:
from pyecharts.charts import Bar from pyecharts.globals import ThemeType bar = ( # 坐标显示x轴数字重叠了,通过增大柱状图的尺寸解决 Bar(init_opts=opts.InitOpts(width="1500px",height="500px",theme=ThemeType.DARK)) # 坐标重叠默认不显示,改一个方向 .set_global_opts(xaxis_opts=opts.AxisOpts(axislabel_opts={"rotate":45, "fontSize":10})) .add_xaxis(list(df['省份'].values)[:34]) .add_yaxis("累计确诊", df['累计确诊'].values.tolist()[:34]) .add_yaxis("新增确诊", df['新增确诊'].values.tolist()[:34]) .set_global_opts( title_opts=opts.TitleOpts(title="累计确诊人数与新增确诊人数情况"), datazoom_opts=[opts.DataZoomOpts()], ) ) bar.render_notebook()
效果图:
-
尝试了一下地图显示疫情数据,在tab中添加多个map,根据不同的关注点显示不同的分布地图,在一个页面中切换不同地图,看起来效果还是不错的。代码如下:
from pyecharts.charts import Tab from pyecharts.charts import Map from pyecharts import options as opts import pandas as pd df = pd.read_excel('data.xlsx') tab = Tab() _map = ( Map(init_opts=opts.InitOpts(theme='dark', width='1000px')) .add("累计确诊人数", [list(i) for i in zip(df['省份'].values.tolist(),df['累计确诊'].values.tolist())], "china", is_map_symbol_show=False, is_roam=False) .set_series_opts(label_opts=opts.LabelOpts(is_show=True)) .set_global_opts( title_opts=opts.TitleOpts(title="新型冠状病毒全国疫情地图", ), legend_opts=opts.LegendOpts(is_show=False), visualmap_opts=opts.VisualMapOpts(is_show=True, max_=1000, is_piecewise=False, range_color=['#FFFFE0', '#FFA07A', '#CD5C5C', '#8B0000']) ) ) tab.add(_map, '累计确诊') _map = ( Map(init_opts=opts.InitOpts(theme='dark', width='1000px')) .add("新增确诊人数", [list(i) for i in zip(df['省份'].values.tolist(),df['新增确诊'].values.tolist())], "china", is_map_symbol_show=False, is_roam=False) .set_series_opts(label_opts=opts.LabelOpts(is_show=True)) .set_global_opts( title_opts=opts.TitleOpts(title="新型冠状病毒全国疫情地图", ), legend_opts=opts.LegendOpts(is_show=False), visualmap_opts=opts.VisualMapOpts(is_show=True, max_=100, is_piecewise=False, range_color=['#FFFFE0', '#FFA07A', '#CD5C5C', '#8B0000']) ) ) tab.add(_map, '新增确诊') _map = ( Map(init_opts=opts.InitOpts(theme='dark', width='1000px')) .add("治愈人数", [list(i) for i in zip(df['省份'].values.tolist(),df['治愈'].values.tolist())], "china", is_map_symbol_show=False, is_roam=False) .set_series_opts(label_opts=opts.LabelOpts(is_show=True)) .set_global_opts( title_opts=opts.TitleOpts(title="新型冠状病毒全国疫情地图", ), legend_opts=opts.LegendOpts(is_show=False), visualmap_opts=opts.VisualMapOpts(is_show=True, max_=1000, is_piecewise=False, range_color=['#FFFFE0', 'green']) ) ) tab.add(_map, '治愈') _map = ( Map(init_opts=opts.InitOpts(theme='dark', width='1000px')) .add("死亡人数", [list(i) for i in zip(df['省份'].values.tolist(),df['死亡'].values.tolist())], "china", is_map_symbol_show=False, is_roam=False) .set_series_opts(label_opts=opts.LabelOpts(is_show=True)) .set_global_opts( title_opts=opts.TitleOpts(title="新型冠状病毒全国疫情地图", ), legend_opts=opts.LegendOpts(is_show=False), visualmap_opts=opts.VisualMapOpts(is_show=True, max_=50, is_piecewise=False, range_color=['#FFFFE0', '#FFA07A', '#CD5C5C', '#8B0000']) ) ) tab.add(_map, '死亡') tab.render_notebook()
效果图如下:
本次项目的难点应该是在对于文本数据的识别与获取,由于并没有相关算法知识的积累,加上找不到爬取文本的项目资料进行学习,我最后还是选择了爬取网页的统计数据,在热点信息那一块的实现也并未使用算法进行筛选。
从零开始学python可以说收获还是很大的,学了pyhon基础语法后,我就接着学爬虫相关的知识,在数据可视化这一块学习还是比较少的,基本上套用别人设计好的图表,进行修改,唯一收获较大的大概就是学会了使用jupyter notebook这一工具。
通过这次项目,我对于python相对于其他语言更适用于人工智能和大数据的原因深有体会,它内置了很多的库函数,方便调用,大大缩减了编写底层逻辑代码所需要的时间,减少了繁琐程度,相对而言的就是增加了配置运行环境的难度。我尝试过使用Anaconda进行虚拟环境的配置,因为各种原因,某些库无法导入,最后放弃了,但是不得不说,python还是每个项目单独配置一个运行环境比较好,最后导出requirements.txt也会方便很多。
Github相关的基础操作我原来就接触过了,这次项目算是一个复习。总的来说项目要求还是相对来说非常完整的,但由于时间太短等问题,我并没有做测试相关的部分,对我来说要求还是太复杂了,两周时间太短,很多东西还需要时间去学,个人能力有待提高。