Python气象数据分析实战:从数据采集到模型预测的完整源码解析

发布时间:2026/10/12 18:44:26
Python气象数据分析实战:从数据采集到模型预测的完整源码解析
简介这份资源是面向高校学生与Python数据分析初学者的气象数据分析与可视化项目源码包适合用作课程大作业、期末项目或自学练手。项目以真实气象数据为对象完整覆盖数据读取、清洗、特征处理、模型训练与结果可视化等环节并配有文档说明便于理解整体实现思路与代码结构。压缩包共22个文件约1.42MB包含4个py脚本承担数据获取、处理、建模与主流程调度4个csv数据文件提供训练与验证样本1个pkl保存训练好的模型另有html页面与多张jpg结果图用于展示可视化效果。已有509人学习下载说明其参考价值获得一定认可。对于需要快速搭建气象分析项目框架、借鉴机器学习预测流程或补充可视化呈现方式的读者可直接运行调试并在此基础上替换数据、调整模型形成自己的课程设计或扩展实验。1. 从一份 95 分气象大作业说起这套 Python 源码到底能跑出什么如果你正在找一份能直接跑通、结构清晰、还带文档说明的 Python 气象数据分析项目那这套「使用 Python 进行气象数据分析与可视化」的源码包值得先看一眼。它不是那种只丢几个 notebook 的碎片代码而是一个完整闭环从天气网抓数据、清洗成 CSV、训练预测模型、最后出可视化图表整条链路都有对应文件。项目本身是个人期末大作业评审分 95 以上说明代码规范度和功能完整度都过了老师那一关。它适合三类人一是正在做数据分析或机器学习课程设计、想找参考实现的学生二是刚入门 Python、想拿一个真实数据集练手 pandas matplotlib sklearn 的初学者三是需要快速搭一个「数据采集 → 建模 → 可视化」demo 的从业者。核心文件包括GetData.py采集、ProcessData.py清洗、GetModel.py建模、main.py主流程外加date_train.csv、date_test.csv、date_valid.csv三份数据和一个训练好的Model.pkl。下面按「先跑起来、再拆原理、最后避坑」的顺序把这份资源拆开讲透。2. 环境搭建与数据链路从 GetData.py 到三份 CSV 的完整走法2.1 依赖清单与 Python 版本选择拿到压缩包先别急着python main.py第一步是确认环境。这份项目用到的库不算多但版本对不上很容易在编码或绘图环节翻车。常见做法是建一个独立虚拟环境避免和你机器上已有的包打架。# 创建虚拟环境建议 Python 3.8 ~ 3.10太新的 3.12 部分老库轮子不全 python -m venv venv # 激活Windows venv\Scripts\activate # 激活macOS / Linux source venv/bin/activate # 一次性装齐核心依赖 pip install pandas numpy matplotlib scikit-learn requests beautifulsoup4 lxml joblib这里每个包都有明确分工requestsbeautifulsoup4lxml负责从天气网页面把原始数据抠下来pandas做清洗和 CSV 读写scikit-learn训练预测模型matplotlib出图joblib用来把模型序列化成Model.pkl。参数上唯一要留意的是 Python 版本——项目里如果用了sklearn的某些接口3.7 以下会报ModuleNotFoundError3.12 又可能遇到distutils被移除的兼容问题所以 3.8 到 3.10 是最稳的区间。提示如果你机器上已经有 Anaconda直接用 conda 建环境也行但别在 base 环境里装否则后面依赖冲突排查起来很痛苦。2.2 数据采集GetData.py 抓的是什么GetData.py是整个链路的上游它的任务是从天气网把历史气象数据抓下来落成china_today.csv这类中间文件。这类脚本的通用结构是「构造 URL → 发请求 → 解析 HTML 表格 → 存 CSV」。下面是我按这个项目场景还原的核心逻辑你可以对照源码看结构是否一致import requests from bs4 import BeautifulSoup import pandas as pd def fetch_weather(url): # 带上 UA很多站点对空 UA 的请求直接返回 403 headers {User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64)} resp requests.get(url, headersheaders, timeout10) resp.encoding utf-8 # 不显式指定中文会变乱码 soup BeautifulSoup(resp.text, lxml) rows [] # 天气网的历史表格通常在 table 标签里逐行取 td for tr in soup.select(table tr): tds [td.get_text(stripTrue) for td in tr.find_all(td)] if len(tds) 4: # 过滤掉表头或空行 rows.append(tds) df pd.DataFrame(rows, columns[日期, 最高温, 最低温, 天气, 风力][:len(rows[0])]) df.to_csv(china_today.csv, indexFalse, encodingutf-8-sig) return df if __name__ __main__: fetch_weather(https://www.weather.com.cn/...) # 换成源码里的实际地址逻辑说明headers里的 UA 是必须的否则大概率拿到 403resp.encoding不设成 utf-8中文城市名和天气描述会变成乱码utf-8-sig是为了让 Excel 打开 CSV 时不乱码。参数上timeout10防止网络卡死len(tds) 4是过滤无效行的经验阈值。这一步产出的china_today.csv就是后续清洗的原料。2.3 数据清洗ProcessData.py 怎么把脏数据变成训练集抓下来的原始数据往往有缺失值、温度带「℃」符号、日期格式不统一等问题ProcessData.py就是干这个的。它最终产出date_train.csv、date_test.csv、date_valid.csv三份文件对应训练集、测试集、验证集。典型处理流程如下import pandas as pd import numpy as np from sklearn.model_selection import train_test_split def clean_and_split(raw_path): df pd.read_csv(raw_path, encodingutf-8-sig) # 1. 去掉温度里的单位符号转成数值 for col in [最高温, 最低温]: df[col] df[col].astype(str).str.replace(℃, , regexFalse) df[col] pd.to_numeric(df[col], errorscoerce) # 转不了的变 NaN # 2. 缺失值处理温度用前后均值填充比直接 drop 保留更多样本 df[最高温].fillna(df[最高温].mean(), inplaceTrue) df[最低温].fillna(df[最低温].mean(), inplaceTrue) # 3. 日期标准化 df[日期] pd.to_datetime(df[日期], errorscoerce) df df.dropna(subset[日期]).sort_values(日期) # 4. 按 7:1.5:1.5 切分训练/验证/测试 train, temp train_test_split(df, test_size0.3, random_state42) valid, test train_test_split(temp, test_size0.5, random_state42) train.to_csv(date_train.csv, indexFalse, encodingutf-8-sig) valid.to_csv(date_valid.csv, indexFalse, encodingutf-8-sig) test.to_csv(date_test.csv, indexFalse, encodingutf-8-sig) return train, valid, test if __name__ __main__: clean_and_split(china_today.csv)逻辑说明errorscoerce是关键参数它把无法转换的值变成 NaN 而不是直接抛异常让流程能继续走fillna用均值填充是保守做法样本量小时比删除更划算random_state42保证每次切分结果一致方便复现。三份 CSV 的划分比例是这类课程项目的常见配置验证集用来调参测试集只在最后评估用一次。注意如果你的原始数据里日期跨度很短切分后某一类可能样本过少训练时会出现警告这时候要么补数据要么调整test_size。3. 建模与可视化GetModel.py 训练逻辑和图表输出怎么对上3.1 模型训练从 date_train.csv 到 Model.pklGetModel.py负责读训练集、训练模型、保存成Model.pkl。这类气象预测项目通常做的是回归任务预测温度或分类任务预测天气类型。下面按回归场景还原核心代码import pandas as pd import joblib from sklearn.ensemble import RandomForestRegressor from sklearn.metrics import mean_absolute_error, r2_score def train_model(): train pd.read_csv(date_train.csv, encodingutf-8-sig) valid pd.read_csv(date_valid.csv, encodingutf-8-sig) # 特征工程把日期拆成年、月、日让模型能捕捉季节性 for df in [train, valid]: df[日期] pd.to_datetime(df[日期]) df[年] df[日期].dt.year df[月] df[日期].dt.month df[日] df[日期].dt.day features [年, 月, 日, 最低温] # 用最低温预测最高温 target 最高温 X_train, y_train train[features], train[target] X_valid, y_valid valid[features], valid[target] # 随机森林对中小规模表格数据很稳不用太多调参 model RandomForestRegressor(n_estimators100, random_state42) model.fit(X_train, y_train) pred model.predict(X_valid) print(MAE:, mean_absolute_error(y_valid, pred)) print(R2:, r2_score(y_valid, pred)) joblib.dump(model, Model.pkl) # 序列化main.py 直接加载 return model if __name__ __main__: train_model()逻辑说明n_estimators100是随机森林的常用起点树太少欠拟合、太多训练慢且收益递减把日期拆成「年/月/日」三个特征是为了让模型学到「7 月比 1 月热」这种季节性规律比直接丢一个时间戳有效得多。joblib.dump保存的Model.pkl是二进制文件加载时用joblib.load即可比 pickle 对大 numpy 数组更高效。评估指标里 MAE 看平均误差多少度R2 看拟合优度这两个数直接决定你答辩时能不能说清模型好坏。3.2 可视化main.py 怎么把结果画出来main.py是主入口串起加载模型、预测、绘图三件事。项目里那批wps*.jpg截图基本就是这里跑出来的图。典型可视化包括温度趋势折线图、真实值 vs 预测值对比图、月度分布柱状图。import pandas as pd import joblib import matplotlib.pyplot as plt plt.rcParams[font.sans-serif] [SimHei] # 中文显示不加这行全是方块 plt.rcParams[axes.unicode_minus] False # 负号正常显示 def visualize(): test pd.read_csv(date_test.csv, encodingutf-8-sig) test[日期] pd.to_datetime(test[日期]) test[月] test[日期].dt.month model joblib.load(Model.pkl) test[预测最高温] model.predict(test[[年, 月, 日, 最低温]]) # 图1真实 vs 预测折线 plt.figure(figsize(12, 5)) plt.plot(test[日期], test[最高温], label真实值, linewidth1.5) plt.plot(test[日期], test[预测最高温], label预测值, linestyle--) plt.xlabel(日期); plt.ylabel(温度(℃)) plt.title(最高温真实值与预测值对比) plt.legend(); plt.tight_layout() plt.savefig(对比图.png, dpi150) # 图2月度平均温度柱状 monthly test.groupby(月)[最高温].mean() plt.figure(figsize(8, 5)) monthly.plot(kindbar, color#4C72B0) plt.xlabel(月份); plt.ylabel(平均最高温(℃)) plt.title(各月平均最高温分布) plt.tight_layout() plt.savefig(月度分布.png, dpi150) if __name__ __main__: visualize()逻辑说明SimHei字体是 Windows 自带黑体Linux 上要换成WenQuanYi Micro Hei之类否则中文标题全是方框axes.unicode_minusFalse解决负号显示成方块的问题这两个配置是 matplotlib 中文绘图的标配。dpi150保证导出图片清晰度够放进报告。跑完这段你就能得到和项目截图里一致的图表。提示如果Model.pkl加载报版本不兼容多半是训练和加载时的 sklearn 版本不一致统一环境即可。4. 避坑与排查这份源码跑不起来时先查这五条4.1 中文乱码CSV 打开是问号、图里是方块现象用 Excel 打开date_train.csv显示乱码或者 matplotlib 图里中文变成一个个方块。原因有两个层面——CSV 层面是编码没带 BOMExcel 默认按 GBK 解析 utf-8 就乱绘图层面是没设中文字体。解决读写 CSV 统一用encodingutf-8-sig绘图前加plt.rcParams[font.sans-serif] [SimHei]和axes.unicode_minusFalse。这两行我每次画中文图都强制走一遍。4.2 路径问题FileNotFoundError 找不到 CSV现象main.py报FileNotFoundError: date_train.csv。原因脚本里用的是相对路径而你在别的目录下执行工作目录对不上。解决要么cd到源码所在目录再运行要么在代码里用os.path.dirname(__file__)拼绝对路径。血泪经验是凡是涉及文件读写的项目路径一律用pathlib.Path(__file__).parent打底换机器也不翻车。4.3 模型加载失败Model.pkl 版本不兼容现象joblib.load(Model.pkl)抛InconsistentVersionWarning或直接报错。原因Model.pkl是在某个 sklearn 版本下序列化的你本地版本不同内部结构对不上。解决要么按源码文档说明装指定版本要么干脆重新跑一遍GetModel.py自己生成新的 pkl。后者更省事反正训练数据都在。4.4 采集被拒GetData.py 返回 403 或空数据现象GetData.py跑完china_today.csv是空的或者请求直接 403。原因目标站点加了反爬空 UA 或高频请求被拦。解决补上User-Agent头请求之间加time.sleep(1)降频必要时换数据源。注意别把采集频率调太高这是基本的工程素养。4.5 依赖冲突numpy 和 pandas 版本打架现象import pandas时报numpy.dtype size changed之类的二进制不兼容错误。原因numpy 和 pandas 版本不匹配常见于混装了 conda 和 pip 的包。解决在干净虚拟环境里用一条pip install命令统一装别东装一个西装一个。实在乱了就删环境重建比逐个排查快。5. 进阶玩法把这份源码改成你自己的项目跑通只是起点真正让这份资源值回票价的是把它改成能写进简历的东西。第一个方向是换数据源和预测目标——现在预测的是最高温你可以改成预测降水量或空气质量指数特征工程里加入「前一天的湿度」「风向」这类滞后特征模型立刻上一个档次。第二个方向是升级可视化项目里用的是 matplotlib 静态图你可以接 pyecharts 或 plotly 做交互式图表鼠标悬停显示具体数值答辩演示效果直接拉满。第三个方向是模型对比。现在只用了随机森林你可以加一个LinearRegression和GradientBoostingRegressor做横向对比用同一份date_test.csv算 MAE 和 R2列成表格放进报告。下面是一个对比脚本的骨架from sklearn.linear_model import LinearRegression from sklearn.ensemble import GradientBoostingRegressor, RandomForestRegressor from sklearn.metrics import mean_absolute_error, r2_score import pandas as pd test pd.read_csv(date_test.csv, encodingutf-8-sig) test[日期] pd.to_datetime(test[日期]) test[年], test[月], test[日] test[日期].dt.year, test[日期].dt.month, test[日期].dt.day features [年, 月, 日, 最低温] models { 线性回归: LinearRegression(), 随机森林: RandomForestRegressor(n_estimators100, random_state42), 梯度提升: GradientBoostingRegressor(random_state42), } for name, m in models.items(): m.fit(test[features], test[最高温]) # 演示用正式评估应在训练集上 fit pred m.predict(test[features]) print(f{name} MAE{mean_absolute_error(test[最高温], pred):.2f} R2{r2_score(test[最高温], pred):.2f})逻辑说明三个模型覆盖了线性、bagging、boosting 三种范式对比结果能体现你对模型选型的理解。参数上GradientBoostingRegressor默认学习率 0.1、树 100 棵中小数据够用。注意上面为了演示直接在测试集上 fit 了正式写报告时一定要在训练集 fit、测试集 predict否则数据泄漏分数虚高答辩被问一句就露馅。验证方法上我一般会做两件事一是把预测值和真实值画在同一张图上肉眼看偏差集中在哪个区间二是算残差分布如果残差随日期有明显趋势说明模型漏了时间特征。这套流程走下来这份源码就不只是「能跑」而是「能讲清楚为什么这么跑」。从那以后我每次拿到别人的项目源码都强制先跑通主流程、再逐文件拆逻辑、最后改一个参数看输出变化三步走完才算真正吃透。希望帮到你。本文还有配套的精品资源点击获取