☰
Python天气预测与可视化:97分课程设计源码全解析
2026/10/10 11:59:03 网站建设 项目流程

简介:这是一份基于Python的天气预测与可视化完整课程设计项目,已获导师指导并通过九十七分高分,面向中高级Python学习者、数据科学初学者及需要完成期末大作业或课程设计的学生。压缩包共二十四个文件,包括四个Python源码文件、四个CSV天气数据集、一个训练好的模型文件、十二张可视化结果截图,以及Markdown说明文档和HTML页面,整体仅一点四三MB,结构紧凑。目前已有六百五十三人学习下载,适合作为课程设计参考。源码按功能模块拆分,涵盖数据抓取、数据预处理、模型训练与主程序,逻辑清晰,便于理解和扩展;自带数据集与训练好的预测模型,无需额外配置即可运行,能直接展示天气预测曲线与可视化图表。项目完整覆盖数据清洗、特征处理、模型训练到图表呈现的全链路,附带的说明文档可帮助快速掌握实现思路,是课程设计提交和入门实践的优质选择。

1. 基于Python的天气预测与可视化:这份97分课程设计源码怎么落地

期末周做课程设计最怕的不是没题目,而是题目看着不难,一跑就翻车。这份基于Python的天气预测与可视化源码包,解决的就是「数据、模型、页面三件事全部齐活」的痛点:GetData抓数据、ProcessData洗数据、GetModel训模型、main出页面,四段式结构把python数据分析与可视化实践大作业该有的环节全部覆盖。项目已经过导师指导拿到97分,适合正在备战期末课程设计、或者想参考一份规范项目结构的同学。压缩包里的CSV数据和Model.pkl都是现成的,按顺序跑完脚本就能完整复现结果,不存在缺文件跑不动的情况。

2. 项目结构与数据管线:从GetData.py到Model.pkl的五段闭环

拿到源码包先别急着跑,花十分钟把文件之间的关系理清楚,后面每一步都知道自己在干什么。

2.1 文件清单与模块职责

压缩包内各文件的分工很明确,先看这张表:

文件职责运行时机
GetData.py从天气网站抓取历史天气与全国主要城市当日天气,落成CSV首次运行或需要换数据时
ProcessData.py读取CSV,清洗缺失值、处理温度单位、拆分日期特征、构造滞后特征每次更换原始数据后
GetModel.py用处理后的训练数据训练随机森林回归模型,导出Model.pkl首次运行或换数据重训时
main.py加载Model.pkl,对测试集做预测,生成天气网.html每次演示前
date_train.csv / date_valid.csv / date_test.csv同一城市三个时间段的天气数据,分别用于训练、调参、验收—
china_today.csv全国主要城市当日天气,供可视化页面的「今日天气概览」使用—
天气网.html最终可视化页面,含温度趋势折线图与全国今日天气由main.py生成,也可直接打开压缩包内这份

四个Python文件刚好对应「采集→处理→建模→应用」四段,这也是课程设计答辩时最容易讲清楚的模块划分方式。导师问「你这个项目怎么组织的」,照着这个顺序说,逻辑是通的。

2.2 数据文件与字段设计

date_train.csv、date_valid.csv、date_test.csv是同一个城市三段不同时间范围的历史天气记录,字段结构保持一致。我在实际项目里常见的列名是「日期、最高气温、最低气温、天气、风向、风力」,日期是唯一用于对齐时间序列的键,最高气温通常作为预测目标。

字段含义是否参与建模
日期东八区日期,格式YYYY-MM-DD拆成年/月/日/星期后参与
最高气温当日最高温度,数值型是,预测目标
最低气温当日最低温度,数值型可作为辅助特征
天气晴/多云/小雨等文本可做LabelEncoder后入模
风向 / 风力文本描述可视化展示用

china_today.csv的结构会多一个「城市」列,它不参与模型训练,服务的是页面里「全国主要城市气温一览」那一块。如果想把项目扩展成多城市对比,往这个CSV里追加行就能生效。

2.3 训练集、验证集、测试集为什么要拆开

很多课程设计只给一个CSV,训练和测试混在一起算,答辩时被问「你怎么证明模型没过拟合」就卡住了。这份源码把数据拆成train/valid/test三段,train用来拟合模型,valid用来调超参数,test最后做一次干净验收。

每一段对应的CSV都在压缩包里,这意味着Model.pkl即使被删了,重新跑一遍GetModel.py也能把整条链路重建出来。很多网上传的python源码大全里十个有八个缺数据,这份好在train/valid/test和模型产物一次备齐,复现时不需要到处找数据。

提示:先跑ProcessData.py,会用前面的脚本生成对应的_processed.csv,后面的训练和预测都依赖处理后的文件。

3. 核心代码拆解:数据处理、模型训练与可视化页面的完整实现

这一章把三个关键脚本逐个拆开讲,读完你能知道每行代码在干什么,参数改哪里、怎么改。

3.1 ProcessData.py:从原始CSV到特征矩阵

数据处理是整个项目里最容易被跳过的环节,但也是最容易翻车的环节。下面是按这份源码的设计思路还原的处理脚本:

import pandas as pd def build_features(raw_path, output_path): df = pd.read_csv(raw_path, encoding='gbk') # 日期列转成datetime类型,再拆出模型能直接消费的数值特征 df['日期'] = pd.to_datetime(df['日期']) df['year'] = df['日期'].dt.year df['month'] = df['日期'].dt.month df['day'] = df['日期'].dt.day df['weekday'] = df['日期'].dt.weekday # 温度列可能带单位文字,先清洗成纯数值 df['最高气温'] = df['最高气温'].astype(str).str.replace('℃', '').astype(float) df['最低气温'] = df['最低气温'].astype(str).str.replace('℃', '').astype(float) # 天气文本做LabelEncoder,保留给后续可视化或特征扩展 df['天气'] = df['天气'].astype('category').cat.codes # 缺失值用前向填充:气温序列短期波动不大,填充最稳 df = df.fillna(method='ffill') # 构造滞后1天特征:昨天最高气温,让模型能看到序列相关性 df['lag1'] = df['最高气温'].shift(1) df = df.dropna().reset_index(drop=True) df.to_csv(output_path, index=False, encoding='utf-8') print('processed ->', output_path, 'rows:', len(df)) if __name__ == '__main__': build_features('date_train.csv', 'date_train_processed.csv')

逻辑说明:日期必须转数值,模型不认「2024-05-01」这种字符串;拆出year/month/day/weekday后,模型才能捕捉「夏天热、冬天冷、周末和工作日温度分布不同」这类规律。滞后特征lag1取前一天最高气温,因为温度变化有惯性,昨天热今天大概率也热,这是时间序列预测里最基础也最有效的一招。

参数说明:encoding='gbk'针对Windows下Excel导出的CSV,macOS/Linux下改成utf-8;shift(1)会产生首行NaN,用dropna()吃掉,如果数据量大想多看两天历史,再加一列df['lag2'] = df['最高气温'].shift(2),但代价是会少两行样本。

3.2 GetModel.py:训练随机森林回归模型并导出pkl

模型部分用的是随机森林回归,不是线性回归,这是有意为之。

from sklearn.ensemble import RandomForestRegressor from sklearn.metrics import mean_absolute_error, r2_score import pandas as pd import joblib data = pd.read_csv('date_train_processed.csv') features = ['year', 'month', 'day', 'weekday', 'lag1'] X = data[features] y = data['最高气温'] model = RandomForestRegressor(n_estimators=200, max_depth=10, random_state=42) model.fit(X, y) # 拿valid集做泛化验证,而不是拿训练集自我感觉良好 valid = pd.read_csv('date_valid_processed.csv') X_valid = valid[features] y_valid = valid['最高气温'] pred = model.predict(X_valid) print('MAE:', round(mean_absolute_error(y_valid, pred), 3)) print('R2:', round(r2_score(y_valid, pred), 3)) # 模型落盘,main.py直接复用 joblib.dump(model, 'Model.pkl') print('Model.pkl saved')

逻辑说明:选随机森林的原因是温度与日期特征之间不是纯线性关系,随机森林能自动学出分段规律,比如「6月到9月高温、12月到2月低温」这类非线性边界,同时不需要做特征归一化,课程设计场景下省去不少预处理步骤。用valid集评估而不是train集,是为了防止「训练集1分、测试集翻车」的假象,答辩时这句话很加分。

参数说明:n_estimators=200表示200棵树,数据量不大时训练很快,树多更稳;max_depth=10限制单棵树深度,防止过拟合;random_state=42固定随机种子,保证每个人复现的结果一致。如果机器配置低,n_estimators降到100差距也不大。

3.3 main.py:从Model.pkl到天气网.html

可视化是这份源码最直观的加分项。main.py做的事情很纯粹:读模型、读测试集、预测、渲染页面。

import pandas as pd import joblib import json model = joblib.load('Model.pkl') test = pd.read_csv('date_test_processed.csv') features = ['year', 'month', 'day', 'weekday', 'lag1'] test['pred_temp'] = model.predict(test[features]) # 把日期、真实温度、预测温度整理成JSON,塞进HTML模板 dates = test['日期'].astype(str).tolist() real = test['最高气温'].round(1).tolist() pred = test['pred_temp'].round(1).tolist() chart_data = { 'dates': dates, 'real': real, 'pred': pred, } html_template = open('天气网_template.html', encoding='utf-8').read() html = html_template.replace('/*CHART_DATA*/', json.dumps(chart_data, ensure_ascii=False)) with open('天气网.html', 'w', encoding='utf-8') as f: f.write(html) print('天气网.html 已生成,双击打开看效果')

逻辑说明:joblib.load把训练好的模型载入内存;特征列必须跟训练时完全一致,少一个列模型都会报错。预测结果通过json.dumps转成JSON文本,替换HTML模板里的占位符/CHART_DATA/,ECharts拿到数据后绘制两条折线:真实温度与预测温度,一眼能看出模型拟合得怎么样。

参数说明:round(1)把温度保留一位小数,页面显示更干净;ensure_ascii=False确保中文日期和城市名正常显示;如果你的模板变量名不是/CHART_DATA/,记得同步改,否则页面会显示空图。

提示:压缩包里的天气网.html是已经渲染好的成品,直接用浏览器打开就能看,重跑main.py会覆盖它。

4. 运行排错避坑:环境依赖、启动顺序与五个高频翻车点

源码跑不起来的原因绝大多数不在代码本身,而在环境、编码和依赖没对齐。

4.1 环境依赖与启动顺序

项目基于Python 3.8+,安装依赖用这一条:

python -m pip install pandas numpy scikit-learn joblib requests bs4 lxml

逻辑说明:pandas/numpy管数据处理,scikit-learn提供随机森林,joblib负责模型存取,requests+bs4给GetData.py做页面抓取。如果只跑可视化和预测,requests和bs4可以不装。

推荐按下面的顺序跑脚本:

python GetData.py # 抓取数据,网络不通时直接跳过 python ProcessData.py # 生成各表的_processed.csv python GetModel.py # 训练并导出Model.pkl python main.py # 生成天气网.html

逻辑说明:这四步是串行依赖,前一步的输出是后一步的输入。Model.pkl已经在压缩包里,跳过GetModel.py也能完成可视化;但data_test_processed.csv需要ProcessData.py先生成,所以ProcessData这一步不能省。

4.2 五个高频踩坑记录

第1条:read_csv中文乱码。 现象:列名和内容全是乱码字符,像“鏃ユ湡”这样的。 原因:Windows下Excel导出的CSV默认GBK编码,pandas读文件默认用utf-8。 解决:read_csv加参数encoding='gbk';如果文件本身已经是utf-8,改成encoding='utf-8'即可,两个编码来回试,哪个不乱码用哪个。

第2条:预测结果几乎全是同一个值。 现象:模型训练不报错,但预测出的温度全部集中在均值附近,曲线变成一条直线。 原因:日期列没有做数值化拆分,模型把日期当成字符串忽略掉了,实际参与训练的只剩lag1一个特征,信息量不够。 解决:回到ProcessData.py确认year/month/day/weekday四列已生成,并检查df.isna().sum(),lag列如果没dropna,NaN会拖垮整个预测。

第3条:GetData.py抓不到数据或者报IndexError。 现象:运行时报空列表,或者索引越界。 原因:天气网站的页面结构改版过,或者请求被反爬拦截。 解决:课程设计不需要死磕爬虫,直接用压缩包里的现有CSV;如果想更新数据,用浏览器开发者工具抓一下最新的接口地址,改GetData.py里的URL即可。

第4条:ModuleNotFoundError: No module named 'sklearn'。 现象:python GetModel.py直接报错退出。 原因:当前Python环境没装scikit-learn。 解决:执行python -m pip install scikit-learn;如果你用的是Anaconda,conda install scikit-learn也行。装完再跑,不要再裸奔。

第5条:天气网.html打开后图表空白。 现象:页面标题和文字都正常,但折线图区域空白。 原因:ECharts是通过CDN加载的,离线环境或校园网拦截导致JS文件没下载成功。 解决:把echarts.min.js下载到本地,模板里的src改成相对路径,例如src="./echarts.min.js",彻底摆脱网络依赖。

5. 模型验证与自定义扩展:换城市重训与页面升级技巧

跑通只是第一步,把模型验证做扎实、把数据换成你自己的城市,这份源码才算真正变成你的作品。

5.1 用date_test.csv做一次严肃的模型评估

很多课程设计交上去,导师问「误差多少」就答不上来。用下面这段脚本可以在终端直接看到测试集上的表现:

python -c " import pandas as pd, joblib from sklearn.metrics import mean_absolute_error, r2_score model = joblib.load('Model.pkl') test = pd.read_csv('date_test_processed.csv') features = ['year', 'month', 'day', 'weekday', 'lag1'] pred = model.predict(test[features]) true = test['最高气温'] print('MAE:', round(mean_absolute_error(true, pred), 3)) print('R2:', round(r2_score(true, pred), 3)) "

逻辑说明:MAE是平均绝对误差,单位是摄氏度,数值越小越好,日常天气预测MAE在3℃以内算合格,超过5℃说明特征或数据有问题;R2越接近1说明模型解释力越强。把这两个指标打出来,答辩PPT里直接放进去,比空口说「效果不错」有说服力得多。

5.2 换城市数据重新训练

这套源码的数据抓取逻辑是按城市维度组织的,想换成别的城市,两步就能完成:先改GetData.py里的城市代码,把新城市的CSV抓下来;然后重新执行ProcessData.py、GetModel.py、main.py三步。如果不想写爬虫,手动从天气网站复制一段时间的历史天气,整理成同名字段存成CSV也可以。

可视化端还有一个容易出效果的改法:把页面里的单折线图扩展成可视化大屏风格。china_today.csv里的全国城市气温数据就是为这个准备的,在天气网.html里加一个横向柱状图,把主要城市按温度排序渲染出来,视觉冲击力比单个折线图强很多,导师看到这种对比视图通常都会给高分。

我第二次跑这套项目时才意识到,第一次翻车全是因为偷懒跳过ProcessData,直接拿原始CSV喂模型,日期被当成字符串,特征维度少得可怜,预测结果当然成了均值曲线。从那以后我每次拿到这类源码,第一件事都是先打印df.dtypes看字段类型,再决定要不要做特征工程,这个习惯帮我少踩了不少坑。希望帮到你。

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

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

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

立即咨询