Python疫情数据分析与可视化实战:从pandas清洗到Flask部署全流程
2026/9/8 8:50:22 网站建设 项目流程

简介:一套面向新冠肺炎疫情数据分析与可视化的Python完整源码,专为期末大作业和课程设计打造,适合需要快速搭建数据分析项目的学生与初级开发者。代码经本地编译验证可运行,评审分为98分,内容经过助教审定,难度适中,能够覆盖从数据清洗、统计分析到图表呈现的完整流程。压缩包共275个文件,大小4.78MB,包括185个CSV格式的疫情时间序列数据、64个PDF文档、9个Markdown笔记、8个PNG可视化图表以及4个Python源文件等,CSV数据涵盖全球及美国多维度记录,Python脚本实现数据处理与绘图,PDF与Markdown辅助说明分析思路和结论。已有128人学习下载。对希望以疫情数据为实战对象完成课程设计的学习者而言,这份资源提供了清晰的目录结构和可直接运行的参考实现,能有效提升大作业完成效率。 如果你的期末大作业还差一个能拿得出手的Python项目,疫情数据分析与可视化是个很稳的选择。这句话我在几个学弟学妹的项目答辩前都说过,不是敷衍——这类项目能同时展示数据清洗、统计聚合、可视化设计和Web部署,正好把一门Python课程里最值钱的东西都串起来。当初我做这个项目的时候,前后花了大概两周,最后拿了90多分,源码也一直留着,后来还被几个学弟借去参考过。这篇就把当时的完整思路、关键代码和踩过的坑都整理出来,给正在做类似数据分析大作业的同学一个能直接抄作业的参考。

1. 项目整体设计与方案选型

1.1 这个项目到底在解决什么问题

别把这个题目想简单了。如果用一句话说清楚,那就是:拿一份真实的疫情历史数据,用Python把它读进来、洗干净、算出有价值的统计指标,最后做成一个能让老师一眼看懂的可视化页面。

很多同学容易犯一个毛病——题目里有“可视化”三个字,就直接去网上找现成的图表套模板,套完就交。这样的作业如果赶上严格点的老师,大概率过不了。因为可视化的本质不是“画图”,而是“通过图讲清楚数据的规律”。疫情数据里有哪些规律可以讲?全国累计确诊随时间的变化曲线、各省份的疫情分布差异、治愈率与死亡率的走势、新增病例的高峰拐点,这些都是有分析价值的点。

这个项目也适合想拿来做简历项目的人。数据分析岗位的面试官一般不看你会不会调包,他看的是你有没有完整走完“数据获取—清洗—分析—可视化”这条链路,以及你在每一步有没有自己的思考。疫情数据是公开的、有话题性的、分析维度多,拿来练手再好不过。

1.2 技术选型:为什么是 Flask + pyecharts

当时我在技术方案上犹豫过几天,备选方案有三个:

方案组成优点缺点
AJupyter Notebook + Matplotlib写起来快,适合自己探索答辩展示效果差,不够“项目化”
BFlask + pyechartsPython体系一致,交互图表好看需要额外学一点Flask
CDjango + ECharts(纯前端)功能强,页面灵活需要写大量JavaScript,工作量翻倍

我最后选的是方案B。

为什么?首先,pyecharts是Python对ECharts的封装,一个Python程序就能生成带交互效果的网页图表,不需要单独去写JavaScript。其次,Flask是Python里最轻量的Web框架,十分钟就能把本地服务跑起来,答辩时打开浏览器现场演示,老师能直接鼠标悬浮看数据,这种“能动起来的图”比pdf截图体面太多。

技术栈确定下来之后,你在报告里就可以光明正大地写:“项目采用Flask框架构建后端服务,使用pyecharts实现数据可视化,通过Bootstrap对页面进行整体排版。”——这句话在答辩时非常加分,因为它说明你做了技术选型的权衡,而不是随便拍脑袋定的。

2. 数据获取与预处理

2.1 数据来源:能用现成数据集就别去爬虫

做数据分析类项目,很多人的第一反应是去爬数据。但我个人建议,除非老师明确要求必须现场爬虫,不然直接用公开整理好的历史数据集更稳妥。原因很简单:疫情数据接口变化频繁,很多早期的数据源已经爬不到了,你花一个下午去调试爬虫代码,不如直接下载一份结构化的CSV文件。

我当时用的是GitHub上某开源仓库整理的历史数据,包含从疫情开始到当年年底的每日记录,字段大概是这些:

  • date:日期,格式为“2020-01-22”这种字符串
  • province:省份名称
  • country:国家/地区
  • confirmed:累计确诊
  • suspected:疑似
  • cured:治愈
  • dead:死亡

拿到数据之后,第一件事不是写图表,而是先打开看一眼规模和结构,这就进入下一步了。

2.2 数据清洗:pandas 基础但必须拿分

数据清洗是整个项目里最“笨”但最容易被老师检查的部分。很多同学直接跳过清洗,上来就画图,图一出来发现数据错得离谱,回头再查就很被动。我的做法是分四步走。

第一步,用pandas读取CSV并预览:

import pandas as pd df = pd.read_csv("covid_data.csv") print(df.shape) # 输出 (行数, 列数) print(df.info()) # 查看每列数据类型和非空值数量 print(df.head()) # 预览前5行

第二步,处理缺失值。疫情数据前期很多省份的疑似、治愈列是空的,不能直接删行,否则会把有效信息丢掉。我当时的处理策略是:数值列直接填0,日期列如果缺失就删掉那一行。

df["suspected"] = df["suspected"].fillna(0) df["cured"] = df["cured"].fillna(0) df["dead"] = df["dead"].fillna(0) df = df.dropna(subset=["date"])

第三步,类型转换。CSV里读进来的数字经常会变成字符串,比如“1,234”这种带千分位逗号的格式,直接聚合会报错,必须先清洗再转类型。

df["confirmed"] = ( df["confirmed"] .astype(str) .str.replace(",", "") .str.replace(" ", "") .astype(int) )

第四步,日期统一成datetime类型,方便后续按时间筛选和排序。

df["date"] = pd.to_datetime(df["date"], format="%Y-%m-%d")

提示:to_datetimeformat参数一定要写对,不写的话pandas会用默认格式去猜,数据量一大很容易出错。你先用df["date"].head()看一眼原始值长什么样,再决定format怎么写。

这一步完成之后,你的数据就已经是“可以分析”的状态了。别小看这几行代码,答辩老师一定会问“你的数据预处理好在哪里”,你把这四步一讲,他基本就不会再为难你。

2.3 指标聚合:从“一堆数字”到“能讲故事”

数据洗干净之后,下一步是计算分析指标。这一步决定了你后面能画出什么图。

我当时主要做了三个维度的聚合:

第一个是全国汇总,看整体趋势。

national = df.groupby("date").agg({ "confirmed": "sum", "cured": "sum", "dead": "sum" }).reset_index()

第二个是各省份汇总,看空间分布。

province_sum = df.groupby("province").agg({ "confirmed": "max", "cured": "max", "dead": "max" }).reset_index()

第三个是算每日新增,看疫情拐点。这一步最值得写进报告。累计确诊是单调递增的,看不出“哪段时间最严重”,但新增确诊是曲线,直观反映疫情扩散速度。

national["new_confirmed"] = national["confirmed"].diff().fillna(0)

diff()是pandas里一个非常实用的方法,算相邻两天的差值,用在这里就是“当天新增”。我还额外算了一个环比增长率:

national["growth_rate"] = national["new_confirmed"].pct_change().fillna(0)

做到这一步,你的数据分析部分就已经超过大多数只画“累计曲线”的作业了。因为你不仅有“现状描述”,还有“变化趋势”和“增长速度”这两个分析维度。

3. 可视化实现与Web部署

3.1 可视化指标与图表类型的对应关系

可视化最怕的是“为了图而图”。我当时给自己定了一条原则:每一张图都必须回答一个具体问题。按这个原则,我做了一张图表选型表,写报告的时候直接把这页截进去,显得整个项目逻辑非常通顺。

分析问题对应指标图表类型为什么用这种图
全国疫情整体走势如何累计确诊、治愈、死亡折线图折线图适合展示时间序列变化趋势
各省份疫情严重程度怎么排各省累计确诊柱状图柱状图适合排名对比
疫情在全球分布如何全球各国确诊地图地图适合空间分布表达
新增高峰出现在什么时候每日新增确诊面积图面积图比折线图更有视觉冲击力

这张表在你写报告、做PPT、答辩的时候都能用,建议直接保留。

3.2 pyecharts 核心图表实战

pyecharts分v1和v2两个大版本,接口差异比较大。我用的v1版本,如果你装的是v2,from pyecharts.charts import Line这种导入方式是一样的,但主题配置和全局项写法上有差异。下面给出最核心的三张图的写法。

全国趋势折线图:

from pyecharts.charts import Line from pyecharts import options as opts line = ( Line() .add_xaxis(national["date"].dt.strftime("%m-%d").tolist()) .add_yaxis("累计确诊", national["confirmed"].tolist(), is_smooth=True) .set_global_opts( title_opts=opts.TitleOpts(title="全国疫情累计趋势"), yaxis_opts=opts.AxisOpts(name="人数"), ) ) line.render("line_national.html")

各省份确诊柱状图:

from pyecharts.charts import Bar bar = ( Bar() .add_xaxis(province_sum["province"].tolist()) .add_yaxis("累计确诊", province_sum["confirmed"].tolist()) .set_global_opts( title_opts=opts.TitleOpts(title="各省份累计确诊排名"), xaxis_opts=opts.AxisOpts(axislabel_opts=opts.LabelOpts(rotate=45)), ) ) bar.render("bar_province.html")

pyecharts生成的是HTML文件,可以直接用浏览器打开,也可以嵌入Flask页面。v1版本需要额外安装地图包才能画地图,这个坑我后面在常见问题部分会详细说。

我把三张图分别命名成line_national.htmlbar_province.htmlmap_world.html,放在templates目录下,方便Flask统一管理。

3.3 Flask 集成与页面自动刷新

Flask集成这一步,是整个项目从“数据分析”升级为“可视化应用”的关键。代码量不大,但结构要清楚。

先搭一个最基础的应用:

from flask import Flask, render_template import pandas as pd app = Flask(__name__) @app.route("/") def index(): return render_template("index.html") if __name__ == "__main__": app.run(debug=True)

然后我把之前分析好的数据导出成JSON放在项目目录里,页面加载时直接读JSON,这样不用每次都重新跑一遍全部分析代码,页面打开速度会快很多。

national.to_json("static/data/national.json", orient="records", force_ascii=False)

模板文件index.html里用iframe把三个图表页面都嵌进来,做成一个大屏效果:

<iframe src="/static/line_national.html" width="100%" height="400"></iframe> <iframe src="/static/bar_province.html" width="100%" height="400"></iframe> <iframe src="/static/map_world.html" width="100%" height="400"></iframe>

注意:如果图表文件里有中文,直接打开HTML时浏览器可能显示乱码,但通过Flask的静态目录访问通常没有这个问题。保险起见,在HTML文件的<head>里手动加一行<meta charset="utf-8">,能避免很多莫名其妙的乱码情况。

自动刷新这块,我用了最简单的办法,在页面<head>里加一行:

<meta http-equiv="refresh" content="30">

这样页面每30秒自动刷新一次,演示的时候数据变化能自动更新,视觉上像“实时大屏”。如果你想做得更高级,可以用JavaScript定时器配合fetch接口从后端拉JSON再动态更新图表,但期末大作业用这个简单方案完全够了。

4. 实战过程记录与可用性检查

4.1 实际跑通一遍的现场记录

我自己在写这个项目的时候,遇到过几次“代码能跑,但页面不对”的情况,最典型的一次是柱状图的X轴标签全部挤在一起,完全看不清省份名。后来我发现是省份数量太多,标签默认不旋转导致的。解决方式就是加一行配置,让标签旋转45度:

xaxis_opts=opts.AxisOpts(axislabel_opts=opts.LabelOpts(rotate=45))

改完之后图立刻清爽了很多。类似的坑还有不少,我把它们整理成了下面的速查表。

问题现象可能原因解决办法
地图显示空白没安装pyecharts地图包pip install echarts-countries-pypkg等对应地图包
图表里的中文字全部变成方块系统缺少中文显示字体换用支持中文的字体,或在pyecharts里配置字体
日期解析报错ValueErrorformat参数与真实数据格式不符先打印原始值,再写匹配的格式化字符串
Flask启动提示端口被占用5000端口被其他程序占用改启动参数为app.run(port=5001, debug=True)
改了CSV数据但页面没变Flask debug缓存关掉页面重新打开,或重启Flask服务
图表渲染出来是空白的JSON数据里混入了NaN值.fillna(0).dropna()提前处理

4.2 一个容易忽略的“高分细节”

做期末大作业和做公司项目不一样,老师看的不只是“代码能不能运行”,还有“你的分析有没有结论”。很多同学图表画得不错,但报告里全是图,没有一句话解释图说明了什么。我当时在每一张图下面都写了一小段分析文字,比如“从折线图中可以发现,疫情高峰期出现在X月X日前后,此后新增病例呈下降趋势”。就这么一个细节,老师在答辩时专门点了出来,说这个做得不错。

另外,尽量把分析结果往“业务结论”上靠,哪怕只是“建议公众在高峰期避免聚集”这种一句话,也会让整个项目显得完整。这里不涉及任何评论,仅仅是数据描述。

5. 常见问题与排查技巧实录

5.1 高频问题速查表

上面那个表格是我实操过程中真正遇到并解决的问题。这里再补充三个高频但不太容易注意的问题。

第一个是库版本兼容问题。当时我用的是pyecharts v1版本,但网上的教程大多是v0.x的写法,from pyecharts import Bar这种老式导入已经不能用了。如果你写的代码反复报ImportError,先看看导入语句是不是from pyecharts.charts import Bar,这是v1之后的标准写法。建议你在虚拟环境里装依赖,不要和系统Python混在一起:

python -m venv venv source venv/bin/activate # Windows下执行 venv\Scripts\activate pip install pandas flask pyecharts

第二个是JSON序列化问题。to_json默认会把中文转成ASCII码,存到文件里全是\u65b0\u589e这种东西。解决办法就是加上force_ascii=False参数,我已经在之前的代码里写了。

第三个是浏览器打开本地静态HTML时报权限错误。如果你直接用file://协议打开HTML,某些浏览器会阻止加载本地文件里的数据。这种时候用Flask启动服务再访问http://127.0.0.1:5000,就不会有这个限制。

5.2 答辩前的最后检查

我总结了一个五分钟快速自检清单,每次交作业之前对着跑一遍:

  • 确认Flask服务能正常启动,浏览器能打开首页
  • 点击每个图表页签,确认没有空白页面
  • df.isnull().sum()检查一遍数据文件里没有未处理的空值
  • 确认报告里说的数据时间范围和代码里过滤的时间范围一致
  • 提前准备一个“如果老师让我现场换一份数据”的方案

最后这条有点意思。有的老师会现场提问:“如果我把数据换成其他国家的,你的代码还能跑吗?”我当时因为代码里把country字段写死了,只能处理中国数据,这一问确实被卡了一下。后来我把筛选逻辑改成了参数传递,老师再问的时候,我现场改一个参数,图表就变了,直接变成加分项。做法很简单,把“全国汇总”的聚合逻辑抽成一个函数:

def agg_by_country(data, country_name): sub = data[data["country"] == country_name] return sub.groupby("date").agg({"confirmed": "sum"}).reset_index()

然后图表代码里调用这个函数,替换图标题和Y轴数据即可。

写在最后

这项目做完之后,我对pandas的groupbydifffillna这些方法的理解比刷十遍教程都深。实践就是这样,真正上手做一个完整的东西,碰到的问题多了,记住的自然就多了。如果你也想做数据分析方向的项目,疫情数据确实是很好的练手素材——量大、维度多、故事性强。先把数据拿下来,图能跑通,再慢慢加分析维度,一步步来。最后再分享一个小技巧:代码注释尽量写清楚“为什么这么做”,而不是“做了什么”,老师翻源码的时候看的是你的思路,不只是结果。

本文还有配套的精品资源,点击获取

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询