基于Python的天气预测与可视化完整实战路线
简介基于Python的天气预测与可视化期末大作业源码包面向正在完成课程设计或期末项目的Python学习者覆盖天气数据爬取、清洗处理、模型预测与可视化展示的完整流程。源码已本地编译可运行评审分95分以上结构分三部分数据获取与处理、预测及评价、可视化展示难度适中适合参考与二次开发。压缩包共24个文件包含4个Python源码文件分别承担网页数据爬取、数据清洗、模型构建与主流程调度4个CSV数据集用于训练与验证12张JPG效果图为运行结果截图可直接查看可视化效果另有天气网HTML模板、训练好的Model.pkl模型文件以及Markdown格式使用文档整体仅1.42MB轻量易上手。使用文档详细列出了环境依赖、运行顺序与参数调整方法并附有常见问题说明即使初学者也能顺利跑通并理解每个模块的作用。已有203人学习下载可作为天气数据分析类大作业的高分参考。1. 从期末大作业到生产级天气应用的进阶路线把“基于Python的天气预测和天气可视化”做成一个高分期末项目难点从来不在“调一个库、画一张图”本身而在于把数据获取、时序建模、可视化呈现和工程落地串成一条完整链路。大多数同学卡住的位置往往是API返回的数据结构和文档对不上、预测模型对波动剧烈的天气数据完全失效、Matplotlib画出的图又丑又密看不清。这篇博文会按照一条可复现的路径展开——先从数据层讲清楚怎么拿干净的历史天气数据再对比两种量级的预测方案统计基线vs轻量深度学习最后落到可视化体系的搭建和期末答辩时能加分的工程细节。整个过程用到的工具覆盖Python安装、环境配置、requests/BeautifulSoup/pandas/Prophet/Matplotlib/Pyecharts等常见组件适合作为期末大作业的主干框架也适合想快速把“能跑的脚本”升级成“能演示的系统”的开发者参考。2. 天气数据的获取与预处理没有干净数据预测和可视化都是空谈2.1 数据源选型免费API和爬虫方案的取舍天气预测项目第一步是拿到足够长的历史数据。实际做期末项目时数据源通常有三种流派调用免费天气API、爬取公开气象网站、使用现成的开源数据集。三者的区别不是在“哪个更高级”而是取决于你的预测目标——如果做未来7天预报直接调用API获取历史同期数据作为训练集最省事如果想做趋势分析爬取按小时粒度的历史气象站数据更有说服力如果只是演示流程Kaggle或Github上的CSV数据集完全够用。一个具体的选型建议是优先找不需要复杂鉴权的HTTP接口。很多气象服务商提供开发版API注册后就能拿到token每日请求量对期末项目来说完全够用。使用requests库请求JSON格式的数据不需要处理Cookie、反爬策略和动态渲染把精力留给后面的预测模型。爬虫方案里BeautifulSoup加requests是常见做法但需要额外处理页面结构变化和请求频率限制在时间紧张时不推荐作为主数据源。2.2 用requests和pandas完成从JSON到DataFrame的转换假设你已经拿到了一个返回JSON格式天气数据的API下面的代码演示了如何用requests拉取历史数据并用pandas做清洗。实际开发中你会面对更复杂的字段这里用最简单结构说明核心逻辑import requests import pandas as pd from datetime import datetime, timedelta def fetch_weather_history(city_code, api_key, days30): 拉取指定城市的历史天气数据 base_url https://api.example.com/weather/history all_records [] for offset in range(days): date (datetime.now() - timedelta(daysoffset)).strftime(%Y-%m-%d) params { city: city_code, date: date, key: api_key, unit: metric } # 注意这里只是演示结构实际API的字段名以文档为准 resp requests.get(base_url, paramsparams, timeout10) if resp.status_code 200: data resp.json() # 提取核心字段日期、最高温、最低温、天气现象、湿度 record { date: date, temp_max: data[result][temp_max], temp_min: data[result][temp_min], condition: data[result][condition], humidity: data[result][humidity] } all_records.append(record) df pd.DataFrame(all_records) df[date] pd.to_datetime(df[date]) df df.sort_values(date).reset_index(dropTrue) return df这段代码的关键点在于循环请求不同日期的数据然后拼装成DataFrame。实际使用时需要注意大部分免费API不支持一次请求返回30天数据循环请求是最稳妥的做法但要控制频率timeout10可以防止某个请求卡死整个循环。pandas.DataFrame的sort_values和reset_index保证了数据按时间升序排列后续建模时这个顺序很重要。2.2.1 数据清洗的典型坑缺失值与时区错位拿到DataFrame之后真正费时间的是清洗环节。天气数据最常见的三种问题某些日期字段返回null、不同日期的时间戳有时区偏差、天气现象字段存在同义不同名比如“晴”和“Sunny”。缺失值最简单的处理方式是用前后两天均值填充df.interpolate()但要注意interpolate默认是线性插值在极端天气突变时会有失真如果缺失率超过20%直接删除对应日期更稳妥。时区问题统一在数据拉取时用datetime标准化绝对不要存两种时区的混合时间。2.2.2 把文本型天气现象编码成模型能用的数值预测模型只能吃数值数据而“晴/多云/小雨/暴雨”这类文本标签必须做编码转换。按照常见做法这里用sklearn.preprocessing.LabelEncoder做标签编码而不是one-hot独热编码——因为LabelEncoder将天气现象映射成0、1、2这样有序整数在树模型和部分线性模型中更容易学到规律。但要注意LabelEncoder对无法比较的类别赋序值有暗示顺序的副作用如果你用的是线性回归换成pd.get_dummies()做哑变量效果更稳。天气现象这种字段本身有程度强弱晴→多云→阴→雨LabelEncoder在这种场景下其实是合理的。3. 天气预测模型从统计学基线到轻量深度学习的渐进路线3.1 为什么ARIMA还在期末项目里有用基线模型的价值天气预测在学术圈已经用上了Transformer、图神经网络这类复杂架构但期末大作业的得分点从来不取决于模型有多前沿而在于你能否清楚解释模型为什么有效、误差有多大、在什么场景下失效。ARIMA作为经典时序模型在平稳天气序列上的表现并不差而且它的参数p,d,q有明确统计含义答辩时可以展开讲。做个ARIMA基线能帮你看清楚数据本身的规律是否有趋势、是否季节波动明显。使用statsmodels库的ARIMA类建立基线模型的代码非常简洁from statsmodels.tsa.arima.model import ARIMA from sklearn.metrics import mean_absolute_error def build_arima_baseline(train, test, order(2,1,2)): ARIMA基线模型order为(p,d,q)三元组 model ARIMA(train[temp_max], orderorder) fitted model.fit() # 预测未来len(test)个时间点 pred fitted.forecast(stepslen(test)) # 计算平均绝对误差用可视化和数值双重验证 mae mean_absolute_error(test[temp_max], pred) print(fARIMA MAE: {mae:.2f}℃) return pred, mae这里有个容易被忽略的细节ARIMA模型的输入要求是pd.Series而不是DataFrame所以要把目标字段单独取出来。order参数的三个值分别表示自回归阶数、差分阶数和移动平均阶数在期末项目里不需要做网格搜索计算量太大手动试几个组合观察差异即可——比如(1,1,1)偏轻、(2,1,2)更灵活、(3,1,3)容易过拟合。ARIMA对非平稳序列的适应性靠的就是d1的差分如果你发现预测结果是一条几乎水平的线多半是差分阶数过大把趋势信息抹掉了。3.2 Facebook Prophet期末项目的“高分模型”ARIMA能交代统计基础但作为主模型不够亮眼。Prophet是Meta开源的时间序列预测库特别适合处理带明显周期性和节假日效应的数据——天气数据恰好就有年周期季节温度变化和月内波动特征。Prophet最方便的一点是只要求ds时间戳和y数值两列接口设计对期末考试场景极度友好。下面是完整建模流程from prophet import Prophet import warnings warnings.filterwarnings(ignore) def build_prophet_model(df, periods7): Prophet预测主模型返回未来periods天的预测结果 # 构造Prophet要求的固定两列格式 prophet_df pd.DataFrame({ ds: df[date], y: df[temp_max] }) model Prophet( yearly_seasonalityTrue, # 开启年度周期性捕获季节温度变化 weekly_seasonalityFalse, # 天气的周周期性不明显关掉减少过拟合 daily_seasonalityFalse, # 期末项目用的是日数据不需要日内周期性 changepoint_prior_scale0.05 # 控制趋势变化的灵活度 ) model.fit(prophet_df) # 生成未来7天的时间点 future model.make_future_dataframe(periodsperiods, freqD) forecast model.predict(future) # 取最后periods行作为预测结果 pred forecast[[ds, yhat, yhat_lower, yhat_upper]].tail(periods) return model, pred这段代码值得重点关注的参数是yearly_seasonality和changepoint_prior_scale。前者对应天气数据的年度温度周期开启后Prophet会自动叠加傅里叶级数来拟合季节性后者控制趋势变化点的灵敏度数值越大模型越容易跟住气温骤变但也可能把噪声当趋势。0.05是默认值对天气数据比较稳。预测结果的yhat_lower和yhat_upper是置信区间画图时用阴影标出来答辩时能直观展示模型的不确定性——这是期末项目的高级加分项。3.3 模型对比与误差分析不能只看准确率预测模型做完后一定要做对比分析。常见做法是把ARIMA和Prophet在同一个测试集上评估用MAE平均绝对误差、RMSE均方根误差两个指标衡量。RMSE比MAE对异常值更敏感如果某天出现极端寒潮RMSE会大幅上升这正好可以用来解释模型对极端天气的局限性。建议在代码里同时输出这两种指标并且计算“预测偏高”和“预测偏低”的天数——天气预测偏向性比绝对误差更能说明问题。import numpy as np def evaluate_model(test_y, pred_y, model_name): 评估模型输出MAE、RMSE和偏差方向 test_y np.array(test_y).flatten() pred_y np.array(pred_y).flatten() mae np.mean(np.abs(test_y - pred_y)) rmse np.sqrt(np.mean((test_y - pred_y) ** 2)) bias np.mean(pred_y - test_y) # 正数说明模型整体预测偏高 print(f{model_name} 评估结果) print(f MAE : {mae:.2f}℃) print(f RMSE: {rmse:.2f}℃) print(f Bias: {偏高 if bias 0 else 偏低} {abs(bias):.2f}℃)评估函数的返回值包含三个维度MAE衡量平均误差水平RMSE放大极端误差Bias判断系统偏差方向比如模型是否倾向于把极端高温预测得偏低。在期末报告的实验分析里用这三个指标对比ARIMA和Prophet是标准的学术写法。如果Prophet在MAE上只比ARIMA好一点点但RMSE明显更小说明Prophet对极值天气的拟合更好——这个结论比“我用的模型很高级”更有说服力。4. 天气可视化体系从Matplotlib基础图到Pyecharts交互大屏4.1 Matplotlib绘制预测对比图标题里最核心的一步可视化是期末大作业的颜值担当。很多同学在这里犯的错误是直接用Matplotlib默认参数画图结果X轴日期标签挤成一片、线条粗细不合适、中文字体显示为方块。下面这段代码解决两个高频问题日期轴刻度稀疏化和中文字体配置。import matplotlib.pyplot as plt import matplotlib.dates as mdates # 解决中文字体问题选黑体或微软雅黑避免默认字体不支持中文 plt.rcParams[font.sans-serif] [SimHei, Microsoft YaHei] plt.rcParams[axes.unicode_minus] False def plot_prediction_comparison(df, pred_df): 绘制历史温度与预测温度的对比折线图 fig, ax plt.subplots(figsize(12, 5)) # 历史真实值 ax.plot(df[date], df[temp_max], label历史最高温, color#2E86C1, linewidth2) # 预测值 ax.plot(pred_df[ds], pred_df[yhat], labelPredicted, color#E74C3C, linestyle--, linewidth2, markero) # 置信区间用半透明填充展示不确定性 ax.fill_between(pred_df[ds], pred_df[yhat_lower], pred_df[yhat_upper], color#E74C3C, alpha0.2, label95%置信区间) # 核心技巧设置日期刻度稀疏化避免标签重叠 ax.xaxis.set_major_locator(mdates.DayLocator(interval3)) ax.xaxis.set_major_formatter(mdates.DateFormatter(%m-%d)) plt.xticks(rotation30) ax.set_xlabel(日期) ax.set_ylabel(温度℃) ax.set_title(天气预测结果对比ARIMA/Prophet可视化) ax.legend() ax.grid(True, alpha0.3) plt.tight_layout() return fig代码里最值得记下来的细节是mdates.DayLocator(interval3)——它在X轴上每3天标一个刻度直接解决搜索热词里“python画图横坐标太密集”的问题。DateFormatter把日期格式化成“月-日”的短格式避免显示完整年份占据太多横向空间。fill_between画的置信区间阴影能让“预测的不确定性”一眼可见这是把一个普通折线图升级成数据科学作品的标志性技巧。4.2 Pyecharts实现交互式天气可视化大屏如果期末作品只交几张静态Matplotlib图那和“可视化”三个字的匹配度明显不够。Pyecharts是基于Echarts的Python交互图表库生成的是能在浏览器里缩放、悬浮显示数值、动态切换的HTML文件拿来当大作业的展示环节非常合适。下面用Pyecharts做一张“城市气温极值对比”的柱状图from pyecharts.charts import Bar, Line from pyecharts import options as opts def create_weather_dashboard(city_stats): 生成城市月均最高温柱状图 cities [item[city] for item in city_stats] avg_high [item[avg_temp_max] for item in city_stats] max_temp [item[max_temp] for item in city_stats] bar ( Bar() .add_xaxis(cities) .add_yaxis(月均最高温℃, avg_high, color#3498DB) .add_yaxis(历史极值℃, max_temp, color#E74C3C) .set_global_opts( title_optsopts.TitleOpts(title多城市气温对比), yaxis_optsopts.AxisOpts(name温度/℃), toolbox_optsopts.ToolboxOpts(), # 自带下载、缩放工具 ) ) bar.render(weather_dashboard.html)Pyecharts的核心优势是ToolboxOpts——生成的图表自带放大、缩小、下载、还原等交互按钮不需要写一行前端代码。这里的数据结构city_stats是一个列表每个元素包含城市名、月均最高温、历史极值三个字段。注意add_yaxis支持多序列可以将“平均温”和“极值温”放在同一张图里对比。在期末答辩时用浏览器打开HTML文件现场操作缩放效果远好于一张静态PNG截图。这个章节主要围绕“可视化”的从静态到交互的演进展开。而一个成熟的期末大作业不应止步于功能呈现还要考虑怎样将数据、预测和图表整理成可交付的说明文档。4.3 折线图与柱状图的组合应用年度温度走势单图呈现单一图表难以完整呈现温度走势的高频波动和整体趋势。这时可以将折线图与柱状图组合在一张图内体现两种数据关系。下面是一个用Pyecharts同时绘制降水柱状图和温度折线图的双Y轴案例def plot_double_axis_weather(df, output_pathweather_combined.html): 组合图柱状图显示降水量折线图显示温度趋势 line ( Line() .add_xaxis(df[date].dt.strftime(%m-%d).tolist()) .add_yaxis(最高温, df[temp_max].round(1).tolist(), yaxis_index1, is_smoothTrue, color#F39C12) ) bar ( Bar() .add_xaxis(df[date].dt.strftime(%m-%d).tolist()) .add_yaxis(降雨量, df[precipitation].round(1).tolist(), color#3498DB) .extend_axis( yaxisopts.AxisOpts(name温度/℃, type_value, positionright) ) .set_global_opts( title_optsopts.TitleOpts(title30天降水与温度趋势), yaxis_optsopts.AxisOpts(name降雨量/mm), legend_optsopts.LegendOpts(pos_top5%), datazoom_opts[opts.DataZoomOpts()], # 加缩放条查看异常密集区域 ) ) combined bar.overlap(line) combined.render(output_path)双Y轴的核心在于坐标轴绑定温度折线用yaxis_index1挂到右侧轴降水量柱状图用默认的左侧轴单位不同的两组数据互不干扰。datazoom_opts增加底部时间滑条解决数据量大时横坐标过长导致的显示拥挤问题。这种组合图的好处是能在一张图里看到“降雨量高的日子气温往往偏低”的相关性在报告里可以直接作为“天气要素相互影响”的证据。5. 从源码到使用文档期末项目的工程化收尾5.1 合理组织项目结构让评委一眼看懂期末大作业源码最忌讳“一个完整脚本从头到尾”。建议按功能把代码拆分到模块参考下面的结构weather_project/ ├── data/ │ ├── raw/ # 原始API返回的JSON │ ├── processed/ # 清洗后的CSV │ └── weather.db # SQLite数据库可选 ├── src/ │ ├── data_fetcher.py # 数据获取模块 │ ├── data_cleaner.py # 数据清洗模块 │ ├── models/ │ │ ├── arima_model.py # ARIMA基准模型 │ │ └── prophet_model.py # Prophet主模型 │ ├── visualization/ │ │ ├── static_plots.py # Matplotlib静态图 │ │ └── interactive_dash.py # Pyecharts交互图 │ └── main.py # 主入口串联全流程 ├── docs/ │ ├── 使用说明.md │ └── 实验报告.md ├── requirements.txt └── README.md模块拆分的意义不只是代码整洁更是在报告里展示工程思维。data_fetcher.py和data_cleaner.py分开意味着数据获取和清洗可以被独立测试models目录单独存放算法文件未来替换模型时不需要动可视化代码。requirements.txt必须写清楚每个依赖库的版本号比如prophet1.1.5这样评委在别的机器上跑你的项目时不会因为版本不一致直接报错。5.2 使用文档的写作逻辑要覆盖“安装-运行-复现”三件事标题里特别强调“使用文档”和“详细使用说明”这部分的写作质量直接决定项目的完整度。一份好的使用文档不应该写成像API手册那样的流水账而应该按“用户视角”组织内容。典型结构如下## 环境准备 本项目基于Python 3.9开发建议使用conda创建独立环境 bash conda create -n weather python3.9 conda activate weather安装依赖pip install -r requirements.txt注意Prophet依赖的cmdstanpy在部分Windows环境中需要C编译环境遇到报错时安装Microsoft C Build Tools可解决。运行项目第一次运行会默认拉取最近30天的历史数据并自动完成清洗、建模、可视化全流程python src/main.py --city 101010100 --days 30其中--city参数填写城市代码--days控制训练数据长度建议不少于14天否则Prophet无法有效学习温度的季节性规律。复现结果运行结束后输出目录下会生成output/prediction.csv未来7天预测结果output/history.png历史与预测对比图output/dashboard.html交互式可视化页面使用文档的关键是把“为什么这样操作”写进说明而不是只丢命令。比如“--days建议不少于14天”这句是因为Prophet需要足够周期才能拟合年度季节性——这种解释在答辩时非常加分说明你不是胡乱定的参数。另外错误处理部分要有针对性你预判用户最可能卡住的环节比如Prophet安装时的编译问题并提供解决路径。 ### 5.3 验证阶段的常用手段核心逻辑正确性检查 期末项目交出去之前最后一道工序是验证数据获取和预测逻辑没有隐性错误。一个实用的验证手段是“历史回测”拿最近7天的真实数据跟预测结果对比计算偏差率。下面这段代码可以加到main.py里作为自检函数 python def self_check(df, model_nameProphet): 用最近7天的真实值验证预测误差 train df.iloc[:-7] test df.iloc[-7:] _, pred build_prophet_model(train, periods7) test_mae mean_absolute_error(test[temp_max], pred[yhat]) # 简单阈值判断模型是否可交付 if test_mae 5: print(f警告预测误差{test_mae:.2f}℃超过5℃建议检查数据源或增大训练集) else: print(f自检通过最近7天预测误差{test_mae:.2f}℃在合理范围内)自检函数选取最近7天作为留出集用前面的数据训练并用模型预测这七天跟真实值对比。阈值取5℃是因为温度预测的MAE如果超过5℃基本等价于“完全没预测准”。自检通过并不意味着模型完美但至少说明“在历史数据上工作的流程没有问题”——这足以证明代码交付的有效性。误差过大时的两条修复路径检查数据源返回的字段映射是否错位最高温当成最低温这类情况频繁发生或者增大训练数据量让Prophet学到更充分的周期特征。5.4 README过时陷阱用示例命令自动验证文档使用文档里最容易被忽视的一个陷阱是版本更新后命令失效但文档忘了同步。常见的做法是在main.py里内置一个演示模式专门用预设的缓存数据跑通全流程而不依赖API调用def demo_mode(): 演示模式不拉取真实API用内置模拟数据验证全链路 demo_df pd.read_csv(data/processed/demo_weather.csv) df_clean clean_data(demo_df) model, pred build_prophet_model(df_clean, periods7) generate_all_visualizations(df_clean, pred) print(演示模式运行完成请打开 output/dashboard.html 查看结果)演示模式是期末项目里很容易被忽略但识别度很高的亮点。它的价值在于如果答辩现场的API服务恰好不可用只要运行python main.py --demo全流程仍然可以被验证。这相当于为项目增加了一层“不依赖外部服务的容错机制”。很多开发者在毕业后回头看自己的期末代码发现README里的命令早就失效——提前做一个稳定的演示模式能在交卷前暴露和过滤掉流程性问题保证项目交付那一刻是“可复现”的。本文还有配套的精品资源点击获取
上一篇/下一篇内容由系统自动关联
返回资讯列表 →