Python疫情数据分析与可视化课程设计:从数据清洗到LSTM预测全流程实战
2026/9/23 15:24:31 网站建设 项目流程

简介:这份资源是面向计算机、电子信息工程、数学等专业大学生的COVID-19疫情数据分析与可视化Python课程设计完整包,适用于课程设计、期末大作业或毕业设计参考。内容涵盖疫情数据获取、清洗、转换、统计分析与可视化全流程,涉及NumPy、Pandas、Matplotlib、Seaborn等数据科学库,并包含时序预测、NLP情感分析、词云与地图可视化等进阶模块,可帮助读者掌握从数据处理到图表呈现的完整技能链。压缩包共66个文件,以17个py脚本、16张png图表、5个csv数据集、5个html页面及ipynb笔记本为主,另含js、md、docx等辅助文件,整体约4.12MB,目录结构清晰,便于按模块检索学习。该课设经导师指导并通过,获得98分,已有62人学习,适合需要高质量参考方案与实操代码的读者。

1. 疫情数据课设资源拆解:一份能跑通全流程的 Python 分析包

去年帮学弟看毕业设计,他拿到的题目是「新冠肺炎疫情数据分析与可视化」,网上搜到的代码要么只有爬虫没有分析,要么图表跑出来全是乱码。后来翻到这份 98 分的课程设计包,从数据采集、清洗、时序预测到 Web 可视化一条龙全带,连答辩用的 docx 报告都在。它解决的不是「教你 Python 基础」的问题,而是给了一个能直接复现、能改参数、能当模板套的完整工程。适合计算机、电子信息、数学专业做课设或毕设的同学,也适合想拿真实数据集练 Pandas 和 Matplotlib 的入门者。包里分了疫情分析和预测、NLP 情感分析两条线,数据文件从 5 月 21 日截断,代码结构清晰,不是那种跑一半就报错的拼凑货。

2. 环境搭建与数据文件结构:从 requirements.txt 到第一张趋势图

2.1 依赖安装与虚拟环境配置

拿到压缩包先别急着 pip install,包里有个pip-selfcheck.jsonpyvenv.cfg,说明原作者用的是 venv 虚拟环境。我一般会先建一个干净的 Python 3.8 环境,因为 Pandas 和 Matplotlib 的版本兼容性在 3.9 以上偶尔会出玄学问题。requirements.txt里列了核心依赖,但没锁版本号,直接装最新版可能遇到wordcloud编译失败。

python -m venv venv source venv/bin/activate # Windows 用 venv\Scripts\activate pip install -r requirements.txt # 如果 wordcloud 报错,单独指定版本 pip install wordcloud==1.8.1

逻辑说明:venv 隔离环境避免污染全局包,requirements.txt里通常包含 pandas、numpy、matplotlib、seaborn、jieba、wordcloud、flask 等。参数说明:Python 版本建议 3.7~3.8,wordcloud在 Windows 上需要 Visual C++ 14.0 编译工具,装不上就下 whl 包手动安装。

2.2 数据文件清单与字段含义

dataSets目录是核心,几个 CSV 决定了后续所有分析能不能跑通。我整理了一份字段对照表,方便改代码时知道每列代表什么。

文件名内容关键字段
countrydata.csv全球各国疫情汇总国家、确诊、死亡、治愈、日期
china_provincedata.csv中国分省数据省份、确诊、疑似、死亡、治愈
yqkx_data-5_21.csv疫情快讯爬取结果标题、发布时间、来源
weiboComments-5_21.csv微博评论数据用户、评论内容、点赞数
API_SP.POP.TOTL_DS2_zh_csv_v2_1075183.csv世界银行人口数据国家、年份、人口数

注意:yqkx_data-5_21.csvweiboComments-5_21.csv的日期截断在 5 月 21 日,如果你要分析后续数据,得自己改爬虫脚本重新抓。人口数据是用来算每万人确诊率的,别漏掉。

2.3 跑通第一个分析 Notebook

疫情分析和预测部分.ipynb是主入口,用 Jupyter 打开后从上往下执行。第一个单元格通常是导入库和读 CSV,这里有个坑:路径写的是相对路径,如果你把 notebook 挪到别的目录会报FileNotFoundError

import pandas as pd import matplotlib.pyplot as plt import seaborn as sns # 设置中文字体,不然图表标题全是方块 plt.rcParams['font.sans-serif'] = ['SimHei'] plt.rcParams['axes.unicode_minus'] = False # 读取中国分省数据 df_china = pd.read_csv('dataSets/china_provincedata.csv') print(df_china.head()) print(df_china.columns.tolist())

逻辑说明:SimHei是 Windows 自带黑体,Mac 用户改成Arial Unicode MSaxes.unicode_minus关掉负号显示问题。参数说明:read_csv如果遇到编码错误,加encoding='gbk'encoding='utf-8-sig'。跑完这一步你应该能看到省份、确诊数等列,如果列名是乱码,说明编码没对。

3. 数据清洗与统计分析:缺失值、增长率与死亡率计算

3.1 缺失值与异常值处理

真实疫情数据里,早期省份数据经常有缺失,比如西藏只有个位数确诊,某些天没上报就是 NaN。直接dropna()会丢太多行,我一般用前向填充加零填充组合。

# 检查缺失情况 print(df_china.isnull().sum()) # 对确诊和治愈列做前向填充,死亡列填 0 df_china['确诊'] = df_china['确诊'].fillna(method='ffill') df_china['治愈'] = df_china['治愈'].fillna(method='ffill') df_china['死亡'] = df_china['死亡'].fillna(0) # 异常值:确诊数不能为负 df_china = df_china[df_china['确诊'] >= 0]

逻辑说明:ffill用前一天的值填充,符合疫情累计数据的单调递增特性。死亡数填 0 是因为早期很多省份确实零死亡。参数说明:如果数据里有重复日期,用drop_duplicates(subset=['省份','日期'], keep='last')去重。

3.2 计算增长率与死亡率

课设报告里要求算每日新增、增长率、死亡率、治愈率,这几个指标是答辩老师必问的。增长率用pct_change()最方便,但要注意分母为 0 的情况。

# 按省份分组后计算每日新增 df_china['新增确诊'] = df_china.groupby('省份')['确诊'].diff().fillna(0) # 计算死亡率 df_china['死亡率'] = df_china['死亡'] / df_china['确诊'] df_china['死亡率'] = df_china['死亡率'].fillna(0) # 计算治愈率 df_china['治愈率'] = df_china['治愈'] / df_china['确诊'] df_china['治愈率'] = df_china['治愈率'].fillna(0) # 按日期汇总全国 df_national = df_china.groupby('日期').agg({ '确诊': 'sum', '死亡': 'sum', '治愈': 'sum' }).reset_index() df_national['新增确诊'] = df_national['确诊'].diff().fillna(0)

逻辑说明:groupby('省份').diff()保证新增是按省算的,不会跨省相减。fillna(0)处理第一天没有前一天数据的情况。参数说明:死亡率保留四位小数用round(4),报告里写百分比就乘 100。

3.3 用 Pandas 做分组聚合分析

除了全国趋势,课设还要求对比不同省份、不同国家的严重程度。groupbyagg能一次性算出多个统计量。

# 各省最高确诊数排名 province_max = df_china.groupby('省份')['确诊'].max().sort_values(ascending=False) print(province_max.head(10)) # 全球各国最新数据 df_country = pd.read_csv('dataSets/countrydata.csv') country_latest = df_country.sort_values('日期').groupby('国家').last() country_latest['每万人确诊'] = country_latest['确诊'] / (country_latest['人口'] / 10000) print(country_latest[['确诊', '每万人确诊']].sort_values('每万人确诊', ascending=False).head())

逻辑说明:groupby().last()取每个国家最后一条记录,即最新累计数据。每万人确诊需要关联人口数据,如果countrydata.csv里没有人口列,就用merge把世界银行那张表并进来。参数说明:sort_values默认升序,加ascending=False变降序。

4. 可视化实战:Matplotlib、Seaborn 与 Pyecharts 地图

4.1 折线图与柱状图:趋势对比

课设报告里的图基本用 Matplotlib 和 Seaborn 出,折线图看趋势,柱状图做排名。这里最容易翻车的是中文显示和日期格式。

import matplotlib.dates as mdates fig, ax = plt.subplots(figsize=(12, 5)) ax.plot(pd.to_datetime(df_national['日期']), df_national['确诊'], label='累计确诊') ax.plot(pd.to_datetime(df_national['日期']), df_national['治愈'], label='累计治愈') ax.xaxis.set_major_formatter(mdates.DateFormatter('%m-%d')) ax.xaxis.set_major_locator(mdates.WeekdayLocator(interval=2)) plt.xticks(rotation=45) plt.xlabel('日期') plt.ylabel('人数') plt.title('全国疫情趋势') plt.legend() plt.tight_layout() plt.savefig('img/trend.png', dpi=150)

逻辑说明:mdates.DateFormatter控制 X 轴日期显示格式,WeekdayLocator每两周一个刻度,避免标签挤在一起。tight_layout()防止标签被裁掉。参数说明:dpi=150保证报告里图片清晰,savefig要在show之前调用。

4.2 热力图与分布图:Seaborn 的用武之地

Seaborn 画热力图适合展示各省在不同时间段的疫情严重程度,heatmap配合pivot_table很直观。

# 取确诊数前 10 的省份,按周汇总 top10 = province_max.head(10).index.tolist() df_top10 = df_china[df_china['省份'].isin(top10)] df_top10['周'] = pd.to_datetime(df_top10['日期']).dt.isocalendar().week pivot = df_top10.pivot_table(index='省份', columns='周', values='新增确诊', aggfunc='sum') plt.figure(figsize=(14, 6)) sns.heatmap(pivot, cmap='YlOrRd', annot=False) plt.title('前十省份每周新增确诊热力图') plt.tight_layout() plt.savefig('img/heatmap.png', dpi=150)

逻辑说明:pivot_table把长表转成宽表,行是省份,列是周数,值是新增确诊。cmap='YlOrRd'是黄到红的渐变,符合疫情严重程度的直觉。参数说明:annot=True会在格子里显示数字,但格子多了会糊,建议关掉。

4.3 Pyecharts 地图与词云

包里mapchina.pymapworld.py用的是 Pyecharts 做地图,比 Matplotlib 的 Basemap 省事。词云用wordcloud.jswordData.py生成,微博评论分词后出图。

from pyecharts.charts import Map from pyecharts import options as opts # 中国地图 map_china = ( Map() .add('确诊数', [list(z) for z in zip(province_max.index.tolist(), province_max.values.tolist())], 'china') .set_global_opts( title_opts=opts.TitleOpts(title='中国疫情分布'), visualmap_opts=opts.VisualMapOpts(max_=int(province_max.max()), is_piecewise=False) ) ) map_china.render('img/map_china.html')

逻辑说明:Pyecharts 输出 HTML 文件,浏览器打开可交互。visualmap_opts控制颜色映射范围,max_设成最大确诊数。参数说明:is_piecewise=False是连续渐变,设True是分段色块。词云部分用 jieba 分词后传给 WordCloud,wordcloud.js是前端渲染用的,别搞混。

5. 时序预测与 NLP 情感分析:LSTM 与微博评论挖掘

5.1 时序预测算法设计

新冠肺炎时序数据预测算法设计.docx里写了预测部分的思路,代码在logistic.py和 notebook 的后半段。常见做法是用 LSTM 或 ARIMA 对累计确诊做拟合,但疫情数据前期增长快后期平缓,直接套模型容易过拟合。

from sklearn.preprocessing import MinMaxScaler from keras.models import Sequential from keras.layers import LSTM, Dense # 取全国每日新增确诊 data = df_national['新增确诊'].values.reshape(-1, 1) scaler = MinMaxScaler() data_scaled = scaler.fit_transform(data) # 构造时间窗,用前 7 天预测第 8 天 X, y = [], [] for i in range(7, len(data_scaled)): X.append(data_scaled[i-7:i, 0]) y.append(data_scaled[i, 0]) X, y = np.array(X), np.array(y) X = X.reshape(X.shape[0], X.shape[1], 1) model = Sequential() model.add(LSTM(50, return_sequences=True, input_shape=(7, 1))) model.add(LSTM(50)) model.add(Dense(1)) model.compile(optimizer='adam', loss='mse') model.fit(X, y, epochs=50, batch_size=32, verbose=0)

逻辑说明:MinMaxScaler把数据压到 0~1,LSTM 对尺度敏感。时间窗 7 天是经验值,对应一周的传播周期。return_sequences=True让第一层 LSTM 输出序列给第二层。参数说明:epochsbatch_size根据数据量调,数据少就减小 epochs 防过拟合。预测结果要inverse_transform还原。

5.2 微博评论情感分析流程

NLP.ipynbsentiments.py做的是微博评论的情感倾向分析。流程是:爬虫抓评论 → jieba 分词 → 去停用词 → 情感打分 → 词云可视化。weibo_战疫情爬虫_spider.py是采集脚本,weiboProcess.py做清洗。

import jieba from snownlp import SnowNLP # 读取评论 df_weibo = pd.read_csv('dataSets/weiboComments-5_21.csv') comments = df_weibo['评论内容'].dropna().tolist() # 情感打分 sentiments = [] for c in comments: s = SnowNLP(c) sentiments.append(s.sentiments) # 0~1,越接近 1 越正面 df_weibo['情感得分'] = sentiments df_weibo['情感标签'] = df_weibo['情感得分'].apply(lambda x: '正面' if x > 0.6 else ('负面' if x < 0.4 else '中性')) print(df_weibo['情感标签'].value_counts())

逻辑说明:SnowNLP 是中文情感分析常用库,sentiments属性返回 0~1 的分数。阈值 0.6 和 0.4 是经验值,可按实际分布调。参数说明:如果评论里有大量表情符号,先正则清洗掉,否则影响分词。jieba.load_userdict可以加疫情相关专有名词,提高分词准确率。

5.3 词云生成与前端展示

wordData.pywordcloud.js配合出词云图,templates目录下是 Flask 的 HTML 模板,server.py启动 Web 服务。

from wordcloud import WordCloud # 拼接所有评论 text = ' '.join(comments) # 结巴分词 words = ' '.join(jieba.cut(text)) wc = WordCloud( font_path='SimHei.ttf', background_color='white', width=800, height=600, max_words=100 ) wc.generate(words) wc.to_file('img/wordcloud.png')

逻辑说明:font_path必须指定中文字体文件,否则词云全是方块。max_words控制显示词数。参数说明:jieba.cut返回生成器,用空格拼接后传给 WordCloud。Flask 那边server.pyrender_template把图表嵌到 HTML 里,uwsgi.ini是部署配置,本地跑直接python server.py就行。

6. 避坑与常见问题排查

6.1 中文显示乱码

现象:Matplotlib 图表标题、轴标签全是方块。原因:默认字体不支持中文。解决:plt.rcParams['font.sans-serif'] = ['SimHei'],Mac 改Arial Unicode MS,Linux 装wqy-microhei并指定路径。

6.2 CSV 读取编码错误

现象:UnicodeDecodeError: 'utf-8' codec can't decode byte。原因:Windows 下 Excel 保存的 CSV 是 GBK 编码。解决:pd.read_csv('file.csv', encoding='gbk')encoding='utf-8-sig',不确定就试这两个。

6.3 LSTM 预测结果是一条直线

现象:模型输出几乎不变。原因:数据没归一化,或者时间窗太短。解决:先MinMaxScaler归一化,时间窗至少 7 天,检查inverse_transform有没有漏掉。

6.4 Pyecharts 地图不显示

现象:HTML 打开空白。原因:地图 JS 文件没加载,或者省份名称和 Pyecharts 内置的不一致。解决:用pip install echarts-countries-pypkgecharts-china-provinces-pypkg装地图包,省份名去掉「省」「市」后缀试试。

6.5 爬虫脚本跑不通

现象:spider-yqkx.py报连接超时或返回空。原因:目标网站改版或加了反爬。解决:检查requests的 headers 有没有带 User-Agent,加time.sleep降低频率,或者直接用包里现成的 CSV 数据做分析,别死磕爬虫。

7. 从课设到毕设:把这份代码改成自己的项目

这份资源最大的价值不是让你照抄,而是给你一个能跑通的骨架。我一般会做三件事把它变成自己的东西:第一,换数据集。包里数据截断在 5 月 21 日,你可以从公开渠道找更新的数据,把dataSets里的 CSV 替换掉,跑一遍清洗脚本看有没有报错。第二,改预测模型。logistic.py用的是逻辑回归,你可以换成 ARIMA 或 Prophet,对比 RMSE 写进报告,答辩时就是亮点。第三,加可视化维度。比如把各省确诊和人口密度做散点图,或者用plotly做交互式大屏,templates里的 HTML 模板改起来不难。

验证方法很简单:跑完 notebook 后检查img目录有没有生成所有图表,results目录里的输出文件是否完整,server.py启动后浏览器能不能打开index.html。如果都正常,说明环境没问题。我习惯在改完代码后把requirements.txt重新生成一遍,pip freeze > requirements.txt,免得换机器又翻车。

从那以后我每次拿到别人的代码包,都先建虚拟环境、锁版本、跑通原始流程再动手改,这个习惯帮我省了无数个通宵。希望帮到你。

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

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

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

立即咨询