news 2026/11/2 2:07:08

气象数据分析实战:从数据清洗到趋势检验的完整实验流程

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
气象数据分析实战:从数据清洗到趋势检验的完整实验流程

简介:这份资源面向数据分析初学者与需要完成课程实验的学生,围绕气象数据展开完整分析实践:通过爬虫代码抓取中国天气网某一城市的天气数据,再对数据做清洗与统计,生成雷达图、条形图等多种可视化图表,并配以分析说明,帮助读者理解从数据获取到图表呈现的完整流程。压缩包共39个文件,约1.69MB,以20个png图表截图、15个xml与4个rels文档结构文件为主,其中png直观展示各类分析结果,xml与rels构成实验报告的文档骨架,源代码可直接用Jupyter Notebook运行。已有1854人学习下载,说明其作为课程实验参考具有一定认可度。读者可获得爬虫源码、可视化绘图代码与整理后的实验报告,便于对照复现分析过程、理解图表选型与结论撰写,适合作为数据分析入门练手或实验课作业的参考模板。

1. 气象分析不是画折线图:一份能跑通的数据分析报告实验包

很多人对气象数据分析的第一印象,就是把气温画成一条折线、把降水画成柱状图,然后贴进报告交差。真到要复现一份完整分析报告时才发现,卡住人的从来不是画图,而是数据清洗、缺测值处理、时间序列对齐、异常年份识别这一整套流程。这份气象分析(数据分析)报告实验资源,解决的正是“从原始观测数据到一份能自圆其说的分析报告”之间的断层。它适合两类人:一类是刚接触数据分析、需要一份完整实验流程照着走的新手;另一类是做过不少业务分析、但没系统处理过气象时序数据的从业者。下面按“资源是什么、怎么用、坑在哪”的顺序拆开讲,每一步都落到可复现的操作上。

2. 数据准备与清洗:把原始观测表变成能算的 DataFrame

气象数据的第一个门槛不在分析,而在“能不能算”。原始观测表常见的问题是列名不统一、日期格式混乱、缺测值用特殊符号标记、单位不统一。这一章先把数据读进来、把类型和缺失处理干净,后面所有分析才有意义。

2.1 读入与列名规范化

常见做法是用 pandas 读 CSV 或 Excel,然后统一列名、统一日期索引。下面这段是资源里数据准备脚本的核心逻辑,我按自己的习惯补了注释和容错:

import pandas as pd import numpy as np # 读入原始观测表,encoding 按实际文件调整,gbk 在部分导出文件里很常见 df = pd.read_csv("raw_weather.csv", encoding="utf-8") # 列名规范化:去空格、统一小写、把中文列名映射成英文 col_map = { "日期": "date", "气温": "temp", "最高气温": "temp_max", "最低气温": "temp_min", "降水量": "precip", "相对湿度": "humidity", "风速": "wind_speed", "气压": "pressure" } df = df.rename(columns={c: c.strip() for c in df.columns}) df = df.rename(columns=col_map) # 日期列转 datetime,无法解析的置为 NaT,方便后面统计坏行 df["date"] = pd.to_datetime(df["date"], errors="coerce") df = df.dropna(subset=["date"]).sort_values("date").reset_index(drop=True) # 数值列强制转 float,非数字(如 "—"、"缺测")会变成 NaN num_cols = ["temp", "temp_max", "temp_min", "precip", "humidity", "wind_speed", "pressure"] for c in num_cols: df[c] = pd.to_numeric(df[c], errors="coerce") print(df.shape, df["date"].min(), df["date"].max())

这段代码的关键点有三个:errors="coerce"让无法解析的值变成NaT/NaN而不是直接抛异常,便于批量统计坏数据;dropna(subset=["date"])只丢掉日期缺失的行,其他列的缺失留到后面按列处理;sort_values("date")保证后续做时间序列时顺序正确。参数上,encoding要根据实际文件试,中文导出文件常见gbk和utf-8两种,读出来乱码就换另一个。

2.2 缺测值处理与单位统一

气象观测里缺测是常态,直接dropna()会把整行删掉,导致样本量骤减。更稳妥的做法是按列判断缺失比例,再决定插值还是剔除。资源里的处理策略是:缺失比例低于 5% 的连续变量用线性插值,高于 5% 的列保留缺失并在报告里注明。

# 统计每列缺失比例 missing_ratio = df[num_cols].isna().mean().sort_values(ascending=False) print(missing_ratio) # 缺失低于 5% 的列做线性插值,limit_direction 保证首尾也能补 for c in num_cols: if missing_ratio[c] < 0.05: df[c] = df[c].interpolate(method="linear", limit_direction="both") # 单位统一:气温若为华氏度则转摄氏度,降水若为英寸则转毫米 if df["temp"].max() > 60: # 粗略判断是否为华氏度 df["temp"] = (df["temp"] - 32) * 5 / 9 if df["precip"].max() < 5: # 粗略判断是否为英寸 df["precip"] = df["precip"] * 25.4

插值方法选线性是因为气象要素在短时间缺口内近似连续变化,limit_direction="both"能补上序列首尾的缺口。单位判断用阈值是权宜之计,正式报告里应该以数据字典为准,这里只是给没有字典时的兜底。做完这一步,数据才算“能算”,后面所有统计和建模都建立在这个干净的 DataFrame 上。

3. 描述统计与趋势分析:让报告里的每个数字都有出处

数据干净之后,报告的主体是描述统计和趋势判断。这一章的重点不是算得多花哨,而是每个结论都能追溯到具体计算,避免“看起来在上升”这种没有依据的表述。

3.1 分季节统计与同比对比

气象分析报告几乎一定会按季节或月份分组统计。资源里的做法是先加时间维度列,再分组聚合,同时算均值和极值:

# 构造季节列,北半球按 3-5 春、6-8 夏、9-11 秋、12-2 冬 def season(m): if m in [3, 4, 5]: return "spring" if m in [6, 7, 8]: return "summer" if m in [9, 10, 11]: return "autumn" return "winter" df["month"] = df["date"].dt.month df["year"] = df["date"].dt.year df["season"] = df["month"].map(season) # 按年+季节聚合,同时输出均值、最大值、样本数 stat = df.groupby(["year", "season"]).agg( temp_mean=("temp", "mean"), temp_max=("temp_max", "max"), temp_min=("temp_min", "min"), precip_sum=("precip", "sum"), days=("date", "count") ).reset_index() # 计算各季节相对上一年的变化,用于报告里的同比描述 stat["temp_yoy"] = stat.groupby("season")["temp_mean"].diff() print(stat.head(10))

agg里同时算均值和极值,是为了报告里既能说“平均气温”,也能说“极端最高温”,两个指标回答的是不同问题。diff()算同比变化,注意要先按季节分组再 diff,否则跨季节相减没有意义。样本数days一定要带上,报告里写“某年夏季均温偏高”时,如果该季节样本只有十几天,这个结论的可信度要打折扣,这是很多报告忽略的点。

3.2 趋势判断:别只看斜率

趋势分析常见翻车点是拿一条线性拟合的斜率就下结论。气象序列有季节周期和年际波动,直接对整段数据拟合会得到误导性结果。资源里的处理是先做年际聚合再拟合,同时给出相关系数:

from scipy import stats # 先按年聚合年均温,消除季节周期 annual = df.groupby("year")["temp"].mean().reset_index() # 线性回归,输出斜率、截距、相关系数、p 值 slope, intercept, r, p, se = stats.linregress(annual["year"], annual["temp"]) print(f"slope={slope:.4f} ℃/年, r={r:.3f}, p={p:.4f}") # 报告里同时给出十年变化幅度,比“每年变化”更直观 print(f"每十年变化约 {slope * 10:.2f} ℃")

linregress返回的p值用来判断趋势是否显著,r值反映拟合强度。报告里写“呈上升趋势”之前,至少要看p是否小于 0.05,否则只能说“未检测到显著趋势”。把斜率换算成“每十年变化”是气象报告的惯例表达,读者更容易理解量级。这一步的坑在于年份样本太少时p值不可靠,一般少于 20 年的序列不建议做强趋势结论。

4. 可视化与报告输出:图要能自己说话

分析做完,报告的说服力很大程度落在图上。这一章讲清楚图怎么选、参数怎么调、输出怎么组织,让图本身能承载结论,而不是靠正文去解释图。

4.1 时序图与分布图的参数设置

时序图看趋势和周期,分布图看极值和偏态,两张图承担不同任务。资源里的绘图脚本用 matplotlib,关键在坐标轴、刻度和标注:

import matplotlib.pyplot as plt import matplotlib.dates as mdates plt.rcParams["font.sans-serif"] = ["SimHei"] # 中文显示 plt.rcParams["axes.unicode_minus"] = False fig, ax = plt.subplots(figsize=(12, 4)) ax.plot(df["date"], df["temp"], lw=0.8, color="#2b6cb0", label="日均温") # 用滚动平均突出趋势,窗口 30 天对应月尺度 ax.plot(df["date"], df["temp"].rolling(30).mean(), lw=2, color="#c53030", label="30日滑动平均") ax.xaxis.set_major_locator(mdates.YearLocator()) ax.xaxis.set_major_formatter(mdates.DateFormatter("%Y")) ax.set_xlabel("年份"); ax.set_ylabel("气温 (℃)") ax.legend(); ax.grid(alpha=0.3) plt.tight_layout() plt.savefig("temp_timeseries.png", dpi=150)

rolling(30).mean()是让趋势线不被日波动淹没的常用手段,窗口大小按分析尺度定,月尺度用 30、季尺度用 90。dpi=150保证报告里插图清晰,tight_layout()避免标签被裁。分布图则用直方图叠加核密度,重点看偏态和极端值位置,参数上bins取 30 左右比较平衡,太少看不出形状,太多噪声大。

4.2 报告结构组织

一份能复现的气象分析报告,结构上建议固定为:数据来源与时段说明、清洗规则与缺失处理、描述统计表、趋势与异常分析、结论与局限。资源里的报告模板把每张图对应到一个小节,图下必须有一句“这张图说明了什么”,避免图堆砌。表格只放关键统计量,完整统计表放附录。这样组织的好处是,别人拿到报告能顺着数据来源一路查到结论,复现时也知道每一步对应哪个输出。

5. 避坑与排查:气象时序分析里最容易翻车的五件事

这一章是我自己踩过、也在别人报告里反复见到的坑,按“现象 → 原因 → 解决”写,照着排查能省不少返工。

5.1 日期解析后顺序错乱

现象:时序图出现来回折返的锯齿,趋势完全看不出来。原因:原始日期格式不统一(有的2020/1/1,有的2020-01-01),to_datetime部分解析失败后被丢掉或错位,排序前索引已乱。解决:解析后先dropna(subset=["date"])再sort_values("date"),并打印df["date"].is_monotonic_increasing确认单调递增。

5.2 缺测值被当成 0 参与统计

现象:某年降水量明显偏低,均值被拉低。原因:缺测标记(如-999、—)被to_numeric转成 NaN 后又被fillna(0)填掉。解决:缺测一律保留 NaN,统计时用skipna=True(pandas 默认),降水求和前先确认该时段缺测天数,缺测多的时段在报告里标注而不是补 0。

5.3 单位混用导致量级错误

现象:气温均值算出 50 多,或者降水总和只有个位数。原因:部分年份用华氏度、英寸,部分用摄氏度、毫米,合并后没统一。解决:在清洗阶段按数据字典统一单位,没有字典时用分位数和物理合理范围做校验,气温合理范围约 -60 到 60 ℃,超出就查单位。

5.4 滚动平均窗口跨年断裂

现象:趋势线在每年 1 月出现断点。原因:rolling按行计算,跨年时窗口内混入了不同年份但时间不连续的数据。解决:先按完整时间序列重采样到日频补齐日期,再做滚动,或者直接用resample("M").mean()做月尺度聚合,避免窗口错位。

5.5 趋势结论忽略样本量

现象:报告写“近五年显著升温”,但被质疑。原因:五年样本做线性回归,p值偶然性大,且未排除城市热岛等非气候因素。解决:趋势分析至少用 20 年以上序列,报告里注明样本年限和显著性水平,结论措辞用“在该时段内呈上升趋势”而非绝对判断。

6. 进阶技巧:用重采样和异常检测把报告做深

基础流程跑通后,想让报告更有分量,有两个方向值得加:一是用重采样把日数据聚到月、季、年多尺度对比,二是用简单异常检测标出极端事件。重采样这块,df.set_index("date").resample("M").agg({"temp":"mean","precip":"sum"})一行就能出月尺度表,注意resample要求 datetime 索引,聚合函数要按变量选,气温用均值、降水用求和,混用会得出没意义的数。异常检测我一般用滚动 Z 分数,窗口取 30 天,阈值设 2.5 到 3,超过就标为异常日:

roll_mean = df["temp"].rolling(30, min_periods=15).mean() roll_std = df["temp"].rolling(30, min_periods=15).std() df["z"] = (df["temp"] - roll_mean) / roll_std df["is_anomaly"] = df["z"].abs() > 2.5 print(df.loc[df["is_anomaly"], ["date", "temp", "z"]].head())

min_periods=15保证序列开头不会因为窗口不满而全是 NaN,阈值 2.5 比 3 更敏感,适合找极端天气过程,但会带来更多误报,报告里要结合天气背景人工复核。这套方法的好处是不依赖分布假设,滚动窗口自动适应季节变化。我自己的习惯是,每次出报告前都强制走一遍“日期单调性检查、缺失比例打印、单位范围校验”这三步,哪怕数据看起来没问题也不跳过,因为翻车往往就出在“看起来没问题”的地方。希望这份拆解能帮到你,把这份实验资源真正跑成自己的一份报告。

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

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/11/2 2:07:05

拓元AI适合哪些人制作AI漫剧和短视频?

拓元AI适合哪些人制作AI漫剧和短视频&#xff1f; 先看创作起点 如果你已经有剧情、剧本&#xff0c;或明确想把内容拆成一套视频制作流程&#xff0c;拓元AI画布值得尝试&#xff1b;如果只想临时生成一个简单镜头&#xff0c;完整工作流未必是必要选择。判断重点不是“会不会…

作者头像 李华
网站建设 2026/11/2 2:06:16

纯NumPy手写全连接神经网络:前向+反向传播实现

简介&#xff1a;这是一份面向深度学习初学者的全连接神经网络原理实践资源&#xff0c;聚焦用纯NumPy从零实现多层感知器&#xff0c;帮助读者透彻理解前向传播、反向传播、权重初始化与梯度更新等核心机制。资源共7个Python源文件&#xff0c;涵盖网络主体&#xff08;networ…

作者头像 李华
网站建设 2026/11/2 2:05:47

Linux操作直觉系统:从ls -i到inode理解的底层实践

简介&#xff1a;本资源是一份面向高校计算机专业本科生的操作系统课程实验报告&#xff0c;聚焦Linux用户接口与编程界面的实践入门&#xff0c;帮助初学者系统掌握命令行操作、系统管理基础及C/Shell程序开发全流程。内容覆盖Linux常用命令&#xff08;ls/uname/man/pwd等参数…

作者头像 李华
网站建设 2026/11/2 2:05:15

FileZilla Server 0.9.39绿色版内网FTP部署与避坑

简介&#xff1a;这份汉化绿色版 FileZilla Server 0.9.39 面向需要在 Windows 环境下快速搭建 FTP 服务的个人站长、网络管理员和软件学习者&#xff0c;免安装解压即可使用&#xff0c;适合局域网文件共享、小型站点资料上传下载及 FTP 服务端功能演练。压缩包仅 1.4MB&#…

作者头像 李华
网站建设 2026/11/2 2:02:03

2020微服务电商代码包跑通:启动顺序、下单链路与事务避坑

简介&#xff1a;面向具备Java与Spring Cloud基础、希望从单体应用迈向分布式架构的后端开发者&#xff0c;这套2020版谷粒商城项目代码以微服务电商为主线&#xff0c;把服务拆分、注册发现、负载均衡、API网关、分布式事务、消息队列、分库分表、分布式缓存、监控日志及CI/CD…

作者头像 李华