简介基于Python的气象数据分析与可视化项目源码包面向Python数据分析初学者及需要完成期末大作业的高校学生提供从数据获取、清洗、建模到可视化展示的完整流程参考。包内共22个文件其中4个py脚本分别承担数据抓取、预处理、模型训练与主程序调用等环节4个csv文件提供训练集、测试集及城市实时天气数据1个pkl文件保存训练好的预测模型12张jpg图片为各步骤运行结果截图1个html文件呈现可交互的天气可视化页面整体仅1.42MB结构清晰、压缩包小巧便于直接运行与二次开发。该项目为个人大作业成果项目评审分达95分以上源码经严格调试确保可运行目前已有509人学习下载。通过这份资源可快速掌握天气数据预处理、机器学习预测及可视化图表的生成思路适合作为课程设计、毕业设计或自学实践的参考模板。1. 气象数据分析实战大多数人会直接卡在第一步用Python做气象数据分析听起来是一条完整链路爬数据、清洗、建模、可视化。但真正动手拆这份期末大作业源码时你会发现这套系统里最有价值的不是模型本身而是它把一条完整的数据流水线拆成了可复用的五个脚本从天气网抓取、CSV清洗、模型训练、预测到生成交互式HTML页面全部串通。尤其适合两类人一类是正在做课设但卡在“数据从哪来”的同学可以把这套代码当作现成的爬取与预处理脚手架另一类是已经会调库但不懂工程化组织代码的入门从业者可以看看别人是怎么管理中间文件的。这篇拆解会沿着文件清单逐层深入把每条命令要改的参数、每个坑在哪、怎么验证结果说清楚让你在跑通代码之外真正能用这套结构套到别的分析任务里。2. 拆包看结构五个脚本一条链路谁在等谁的输出拿到压缩包先别急着运行源码包的文件名其实已经暴露了完整的执行顺序。压缩包里有两类文件一类是脚本另一类是中间产物。搞清楚哪些是生成的、哪些是你必须自己准备的跑起来才不会缺文件报错。2.1 文件清单与依赖关系这份资源的核心可执行文件是五个GetData.py、ProcessData.py、GetModel.py、main.py以及一个HTML模板文件“天气网.html”。数据文件里date_train.csv、date_test.csv、date_valid.csv是划分好的训练/测试/验证集china_today.csv是当天全国天气快照Model.pkl是训练产出的模型文件。wps开头的那些图片是作者当时生成的图表截图相当于运行结果的参考样例不是必须文件。依赖关系如下GetData.py负责从天气网抓取原始数据并生成date_train.csv等文件ProcessData.py读入原始CSV做日期解析、数值清洗输出清洗后的中间表GetModel.py读取处理后的训练数据训练模型并保存为Model.pklmain.py加载pkl和china_today.csv做预测并渲染天气网.html。图片里那些wps图表本质上是main.py输出的matplotlib图表的截图归档。安装依赖之前建议先核对Python版本。这套代码按Python 3.6以上的语法写的用了f-string用Python 3.8或3.9最稳。依赖主要是requests、pandas、numpy、matplotlib、scikit-learn。如果环境里已装了Anaconda直接用conda创建一个干净环境最省事conda create -n weather python3.9 conda activate weather pip install requests pandas numpy matplotlib scikit-learn这里的逻辑是先用conda隔离环境再用pip装纯Python库避免把系统Python搞乱。很多人在自己机器上跑别人的课设源码报错往往是版本冲突比如pandas老代码用了append方法新版pandas会提示被移除先建独立环境这类问题少一半。2.2 先跑哪一步脚本执行顺序不能乱因为脚本之间有强依赖执行顺序错了会报“FileNotFoundError”或“Model.pkl not found”。正确顺序是先GetData再ProcessData再GetModel最后main。我的习惯是拿到开源代码先不看算法直接把每个脚本的__main__入口扫一遍你就能在30秒内画出调用链。比如GetData.py里通常会有类似这样的入口if __name__ __main__: load_history_data()ProcessData.py里可能既有独立的工具函数也有对刚才生成CSV的再加工入口。这里最关键的一条经验如果没把握顺序用PyCharm或VSCode的调试模式在ProcessData.py开头打上断点看它import了哪个模块、读取了哪个文件路径就明白前置依赖是什么。路径通常是相对当前工作目录的所以命令行运行时要在脚本所在目录执行否则文件找不到。3. 数据获取与预处理从天气网抓取到date_train.csv的清洗细节这一章是整个资源里最容易被当黑匣子跳过、但实际上最影响结果的部分。气象数据的特点是字段类型混乱、日期格式不统一、缺失值占比不低。直接把原始数据丢给模型训练出来的准确率会很难看。3.1 抓取脚本的工作方式与请求参数GetData.py按常见的城市和日期参数从天气网按天抓取天气记录。典型代码会定义城市ID列表和历史日期的起始范围通过requests.get拼接URL再用正则或pandas.read_html解析表格。实际操作中一个适合教学课设的做法是import requests import pandas as pd def fetch_weather(city_code, start_date, end_date): base_url https://example-weather-api.com/data headers { User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64), Referer: https://example-weather-api.com/ } date_range pd.date_range(startstart_date, endend_date, freqD) rows [] for single_date in date_range: params { city_code: city_code, date: single_date.strftime(%Y%m%d), } resp requests.get(base_url, paramsparams, headersheaders, timeout10) data resp.json() rows.append({ date: single_date, high_temp: data.get(high, ), low_temp: data.get(low, ), weather: data.get(weather, ), wind: data.get(wind, ) }) return pd.DataFrame(rows)注意这里的核心技巧headers里的User-Agent必须设置不设置会被部分站点直接拒绝timeout参数要加防止某个日期请求挂起导致全脚本卡死。参数说明上city_code对应城市编号start_date和end_date控制抓取区间这两个参数决定了训练集的时间跨度。很多人新学的爬虫会忽略拉取频率控制同一个站点连续请求时最好在循环里sleep 1到2秒这也是为什么完整版脚本通常会在这里加一个time.sleep。3.2 数值列清洗和日期解析的硬规则ProcessData.py承担的是核心的数据清洗。气象数据最常见的三个活儿是日期字符串标准化、温度列从字符串里提取数字、风向风速拆分。以温度为例原始数据里常见的是“23℃/12℃”这种格式必须转成两列数值。一个稳妥的写法是import pandas as pd import re def parse_temperature(temp_str): if pd.isna(temp_str): return None, None nums re.findall(r-?\d, str(temp_str)) if len(nums) 2: return int(nums[1]), int(nums[0]) if len(nums) 1: return int(nums[0]), int(nums[0]) return None, None def clean_weather_df(raw_df): df raw_df.copy() df[date] pd.to_datetime(df[date], format%Y-%m-%d, errorscoerce) df[[high_temp, low_temp]] df[temp_str].apply( lambda s: pd.Series(parse_temperature(s)) ) df df.dropna(subset[date, high_temp, low_temp]) df df.sort_values(date).reset_index(dropTrue) return df这段代码的逻辑是用正则一次性提取温度字符串中的正负整数然后按high/low的顺序填入两列。用errorscoerce非常关键这样解析失败的日期会变成NaT后边的dropna会把这些脏行物理删除不会让脏数据混进训练集。参数说明format里写了“%Y-%m-%d”如果原始数据里是斜杠格式就要改成“%Y/%m/%d”这是最常见的翻车点。3.3 数据划分的时间顺序陷阱date_train.csv、date_test.csv、date_valid.csv这三个文件的划分方式在气象预测任务里一般是按时间顺序切的而不是像经典机器学习那样随机打乱。原因很简单天气预测是按时间序列外推如果用随机抽样划分训练集里出现未来日期、测试集里出现过去日期模型相当于作弊评估分数会虚高。检查代码时会发现ProcessData.py里通常有类似df.iloc[:7000]这种切片方式前70%做训练中间15%做验证最后15%做测试。这里有一个必须提醒的坑时间序列数据不能直接用scikit-learn的train_test_split除非你设置了shuffleFalse。见过不少同学在这里翻车切成随机切片之后模型跑出来的准确率特别高换个时间区间马上失效这就是数据泄漏。验证的办法很简单打印出训练集和测试集的日期区间如果月份有交集逻辑就有问题。4. 机器学习建模与模型落盘天气预测用哪种模型、参数怎么设数据清洗完之后GetModel.py负责训练模型。这个脚本选择什么样的算法作为baseline决定了整个项目能拿到多少分。很多期末大作业项目会直接上LSTM或Prophet但这份资源用的是scikit-learn体系内的模型主要原因有两个一是数据量不大东北部某站的逐日数据也就几千行深度学习难以发挥二是课程的要求一般落在数据分析和可视化上不是追求SOTA精度可解释性反而更重要。4.1 特征工程的构造方式训练前最重要的工作是把日期转换为周期性特征。直接拿日期字符串做特征没法训练常见做法是把日期拆成年、月、日、星期几、是否节假日等。更进一步可以把“月”和“日”转成周期性编码用sin/cos函数保留相近日期在特征空间里的邻近关系import numpy as np import pandas as pd def add_temporal_features(df): df_feat df.copy() df_feat[year] df_feat[date].dt.year df_feat[month] df_feat[date].dt.month df_feat[day] df_feat[date].dt.day df_feat[dayofweek] df_feat[date].dt.dayofweek df_feat[month_sin] np.sin(2 * np.pi * df_feat[month] / 12) df_feat[month_cos] np.cos(2 * np.pi * df_feat[month] / 12) df_feat[day_sin] np.sin(2 * np.pi * df_feat[day] / 31) df_feat[day_cos] np.cos(2 * np.pi * df_feat[day] / 31) return df_feat这里的参数说明很重要month_sin和month_cos合在一起保留的“月份相近”信息让1月和12月可以互相靠近。如果你只放原始月份值模型会认为1月距离12月很远但实际上它们在季节上是相邻的这个正弦编码是气象时间序列特征工程里很经典的技巧比单调递增的数值列合理得多。4.2 回归模型的选择与调参建议温度预测属于回归任务我倾向于让模型对比随机森林和梯度提升回归器。随机森林的优势是不需要精细调参就能得到一个能看的baseline默认n_estimators100时效果就过得去。梯度提升回归器则能进一步压小误差但需要防过拟合。GetModel.py里的训练模式大致是from sklearn.ensemble import RandomForestRegressor import joblib features [year, month, day, dayofweek, month_sin, month_cos, day_sin, day_cos] X_train train_df[features] y_train train_df[high_temp] model RandomForestRegressor(n_estimators200, max_depth10, min_samples_leaf5, random_state42) model.fit(X_train, y_train) joblib.dump(model, Model.pkl)关键参数是max_depth和min_samples_leaf。课设项目的数据量几千行max_depth不设限制的话树很容易长到很深总是完美拟合每个训练样本验证集误差反而上浮。min_samples_leaf5是防止叶子节点样本太少导致方差过大。random_state42固定随机种子两个随机性来源必须固定一是模型内部的bagging抽样二是特征分裂时的随机候选特征选择。4.3 模型验证与得分报告训练完之后代码会在验证集上计算平均绝对误差MAE和R²得分。这里最值得抄的一件事是作者把真实值和预测值的折线图画在同一张图上然后分别对训练集和验证集做对比能直观看出模型是否过拟合。判断标准很朴素训练集误差低、验证集误差高那基本就是过拟合。把验证集MAE和训练集MAE同时打出来相差超过2℃你就要回头调整上边的max_depth。Model.pkl的落盘用joblib.dump加载时用joblib.load这比pickle更稳因为它对numpy数组和大型树模型的序列化优化更好。注意如果换机器运行Model.pkl只包含模型参数不包含训练数据运行时只需要特征列存在匹配main.py里的处理逻辑即可。5. 可视化落地与排查天气网.html的动态渲染和常见问题main.py做的事是串联最终预测结果并生成页面。它读取便于展示的china_today.csv和Model.pkl对每天的温度做预测最后把图表和数据写进“天气网.html”模板里。这个文件用交互式网页这种方式来承载预测结果比在Jupyter Notebook里展示更容易交给老师或客户验收因为对方只需要打开浏览器。5.1 HTML渲染与matplotlib图表保存常见的做法是用matplotlib生成图表并保存为base64编码嵌进HTML而不是让页面动态请求图片文件。这样交付给别人时只要单个HTML文件就能全部展示不会丢图。先展示典型的matplotlib中文乱码规避写法import matplotlib.pyplot as plt import base64 from io import BytesIO plt.rcParams[font.sans-serif] [SimHei, Microsoft YaHei] plt.rcParams[axes.unicode_minus] False fig, ax plt.subplots(figsize(12, 5)) ax.plot(real_dates, real_temps, label实际温度, linewidth1.5) ax.plot(predict_dates, predict_temps, label预测温度, linewidth1.5, linestyle--) ax.set_title(未来一周最高气温预测) ax.legend() buf BytesIO() plt.savefig(buf, formatpng, dpi150, bbox_inchestight) img_base64 base64.b64encode(buf.getvalue()).decode(utf-8) plt.close(fig)核心逻辑是先用BytesIO把图存到内存流里再转成base64字符串通过HTML的img srcdata:image/png;base64,...注入模板。如果不设置plt.rcParams[font.sans-serif]图里的中文会变成方框。还有就是必须在savefig之后立即plt.close否则连续生成多张图时内存会一直涨不仅每次图表重叠严重时还会拖垮后续渲染。5.2 常见问题排查三个高频报错这里跳到一个独立章节集中写这套资源最常遇到的报错和排查方案。现象一运行GetData.py报requests.exceptions.ConnectionError。原因大多不是代码问题而是目标站点在第一次请求后校验了SSL证书或者本机网络环境对出站请求做了限制。解决方法是先独立测试目标域名是否可用再在requests.get里加verifyFalse并给请求头补全Accept与Accept-Language字段。现象二ProcessData.py运行完没有报错但打开date_train.csv发现所有温度列都是空。原因是我之前说的正则提取失败因为原始数据里温度格式可能是“23.5℃”这种带小数点的格式而正则只匹配整数。解决方法是统一先用replace去掉“℃”保留纯数字部分再判断是否需要转浮点。现象三main.py渲染HTML时模板里的大括号和f-string冲突导致页面只显示一串Python代码。原因是f-string里使用了大括号来表示CSS样式块。解决方法是把CSS部分保留为普通字符串拼接f-string只处理动态的图片和表格数据或者用字符串模板的replace方法替换占位符。5.3 更换城市与重新抓取数据的完整流程这份资源最容易被忽略的扩展点是城市维度的替换。操作流程分成三步第一步在GetData.py里更换city_code为新的城市编码第二步把start_date往前拉长到至少五年保证数据量足够第三步重新执行GetData、ProcessData、GetModel三个脚本最后再看main.py的输出。注意改城市后旧Model.pkl必须删除重新生成否则用了之前城市训练的模型来预测新城市的数据结果完全不可信而且不会有任何报错提示是隐性的逻辑错误。6. 把气象预测拆成可复用模板从单次跑通到换数据源也能用的工程习惯整套代码跑通之后我建议你别满足于“能出图”这个结果。这份资源真正的价值在于它的文件划分方式本身就构成了一套小型数据处理管线模板换个数据源、换一个时间序列预测任务结构能直接复用。以下三个习惯能让你把它改造成自己的工具包。第一个习惯是固定中间产物命名。date_train.csv、date_valid.csv这类命名一旦在脚本里被多处引用就不要随意改成带版本号的类似“temp_20241001.csv”的命名方式。如果非要改那就同时修改所有import这些文件的脚本。更稳的做法是单独维护一个config.py的配置项把输入输出文件名集中管理避免文件路径散落在各个脚本里。这样做的好处是当你要把训练数据从天气数据换成股票日线数据时不需要打开ProcessData.py一行行地毯式搜索所有出现日期解析的地方。第二个习惯是给每个脚本的必要输出打印摘要行。每次跑完ProcessData.py后强制print出数据框的形状、列名、日期范围做到任何一次异常都能立刻发现。从这套源码里我能看出当时作者在调试的时候没少做这件事因为中间产物的命名和对齐程度明显是经过好几轮人工检查的。你后续接手之后应该在这个基础上保留print摘要的写法而不是把它删掉因为删掉后运行一套流水线后只能看到黑匣子出了问题完全不知道哪个环节错了。第三个习惯是版本留痕。GetModel.py生成的Model.pkl在多次调参后可能被新模型覆盖。翻车过一轮之后我现在每次重新训练前都强制把上一版拷贝成Model_backup.pkl。这样如果新模型效果反而变差还有后悔药可以吃。对实验性的改动最好在文件名上附带时间戳比如Model_1210.pkl然后在main.py的加载处把文件名常量抽出来方便快速回到旧版本。这是很多教学代码里不教的工程习惯但实际做项目和课设答辩时非常加分至少被问到“如果模型效果不好怎么回退”时你不会懵。最后如果你也是自学的从业者而不是在校学生建议把这份资源里所有直接抓取逻辑改为读取本地CSV的接口这样既能保留完整流程又不会因为站点改版而全部失效。用这套结构做完一个可复现的时间序列预测Demo之后再把爬虫部分换成别的公开数据源就能在实际工作中直接复用了。希望这套拆解能帮到你至少遇到气象数据项目时少走几段弯路。本文还有配套的精品资源点击获取
阅读完成 · 觉得有帮助?