news 2026/10/11 17:01:09

全国省市县三级逐日最低气温数据处理与GIS应用指南

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
全国省市县三级逐日最低气温数据处理与GIS应用指南

拿到这类数据包,我最怕的不是文件太大,而是打开之后“看起来正常、用起来全错”。1980-2024年全国省市县三级逐日最低气温数据,听上去就是一张干干净净的Excel表加几个Shapefile,但真放进GIS里操作,编码、单位、日期格式、行政区划变动,每个环节都能让你的成果图变成一张噪声图。下面这篇就把我从“解压数据”到“出图分析”整个流程里遇到的关键问题逐个拆开讲清楚,包含字段结构、格式陷阱、应用场景、数据清洗和验证方法,适合刚接触这类日尺度气象栅格/行政区统计数据的GIS从业者、气象分析人员和农业、能源领域的研究者参考。

1. 数据集整体结构:45年逐日记录到底意味着什么

1.1 时间维度:1980-2024的日历天数和序列组织方式

1980年1月1日到2024年12月31日,含首尾,一共45个年份。很多人会想当然地认为45年就是45乘365天,但里面还有12个闰年,所以完整日历天数是16437天。这意味着,如果你把一个县级、逐日、全字段的数据放在一张Excel表里,全国大约2800个县级行政区,累积下来接近5000万行记录。所以这类分享数据基本不会真的给你一个“无敌大工作簿”,更常见的组织方式是“按年份拆分”“按月份拆分”或者“按日期拆出成千上万个文件夹”。

拿到手之后,不要急着双击打开最大那个Excel,先看目录树。目录里通常会有年份文件夹,里面再按月份或日期放置文件。对日尺度数据来说,日期是可检索性最高的维度,也是后续做时间序列分析时最容易踩坑的地方。如果数据包结构很混乱,我的建议是先统一整理为“日期、行政区划代码、行政区划名称、最低气温”四列的长表,再存成Parquet或CSV,后续随便怎么筛选聚合都顺畅。

1.2 空间维度:省、市、县三级的组织逻辑

“省市县三级”不是普通的粒度堆叠,它意味着同一个时点同一份气温被重复记录了三轮:

  • 省级一份,每天大约几十行;
  • 市一级一份,每天大约三百多行;
  • 县一级一份,每天大约两千八百多行。

三级数据单独看都能用,组合起来更有意思。基层研究用县级,区域对比用市或省,不同层级之间可以互相验证。比如县级数据某天出现一个异常低温值,用上一级市级面的均值去核验,往往能很快判断是真实极端事件还是数据错位。

需要留意的是,行政区划不是一成不变的。过去几十年里,撤地设市、撤县设区、设立新县级单位这些事情非常多。因此数据包里的“现行行政区划”和“历史某一年的真实区划”可能存在差异。做跨年对比时,尽量使用“行政区划代码”而不是行政区划名称来进行关联和匹配,名称相似但代码不同的情况在长期序列里几乎必然存在。

1.3 Shp和Excel的定位:一个管图,一个管数

Shp和Excel不是同一份数据的两种简单复制,它们服务的分析流程完全不同。

Shapefile适合空间可视化。一个县一个面要素,属性表里挂着温度值,打开GIS就能画出等值区域图。但Shapefile由多个同名文件组成(.shp、.dbf、.shx、.prj等),发送或拷贝时一旦漏掉.dbf,属性表就全空了。温度数据的关键字段都在.dbf里,所以看到.shp文件时,务必确认旁边几个辅助文件都在。

Excel则更适合做统计建模。数据按行列存放,日期是一列、区域代码是一列、温度是一列,用Pandas或R语言读进来后,可以轻松做分组统计、面板回归、机器学习特征工程。Excel格式最大的问题在于数据量太大时运行卡顿,所以建议不要直接打开编辑,先转化成更为高效的数据格式。

维度Shapefile格式Excel格式
核心用途制图、空间分析、切片展示表格清洗、统计建模、跨表合并
最小分析单元一个行政面要素一行时间-区域记录
易碎点多个辅助文件缺失、编码乱码行数过多、日期类型混乱
适用人群GIS制图师、遥感分析者数据分析师、科研人员

2. 打开文件前必须弄懂的字段与格式细节

2.1 Shapefile属性表里的中文字段和编码问题

中文属性表乱码是我见过最多的“假故障”。表现很直接:QGIS里打开属性表,省、市、县名称全部变成“锟斤拷”或者“?”一类内容。原因不是数据坏了,而是Shapefile的.dbf文件本身用GBK或GB2312编码存储中文字符,而GIS软件默认按UTF-8解析。

解决办法很简单:在加载Shapefile时,把数据源编码手动指定为GBK或GB18030。QGIS的“数据源编码”选择里通常有“GBK”“System”等选项,切换后重新加载即可。如果所有办法都试过仍然乱码,可以用Notepad++打开.dbf附近的.cpg文件查看编码声明,再按声明指定编码。编码问题解决之前,最好不要对字段做任何重命名或导出操作,避免把错误编码固化到新文件里。

2.2 坐标系统、单位和读数精度的判断

这类行政区温度数据大多是经纬度坐标系,常见的是WGS84或CGCS2000,投影坐标也可能出现。打开图层后,如果和在线底图错位很远,先看是否把十进制度数当成了平面坐标;如果只是几十米的偏移,可以检查是不是参考椭球或坐标系定义略有差异。

对气温数值来说,坐标系影响不大,但平面投影与经纬度存储会影响距离计算和面积统计。我的习惯是:日常查看用经纬度坐标,计算县域面积或做格点插值时再投影到当地合适的平面坐标系。

2.3 温度单位:直接是摄氏度,还是缩放了10倍

这是最隐蔽的坑之一。很多气象数据为了节省存储空间,会把温度乘以10记录成整数,比如-3.5℃写成-35,0.6℃写成6。如果你没有看字段说明,直接把-35当零下35度画图,整张图就会“异常偏冷”,而且很难发现。

判断方法很简单:载入数据后先看最低气温列的取值范围。如果大部分值落在-450到400之间,基本可以确定是0.1℃单位;如果正常分布在-50到45之间,才是标准摄氏度。对于0.1℃单位的数据,处理时除以10即可。

提示:不要在看到“-320”时先怀疑极端寒潮,先检查缩放系数。这类错误在全量数据里不会只出现一两个,而是整体偏移,特征非常明显。

2.4 Excel日期列的三种存储形态与解析方法

Excel日期列常见三种形态,处理方式完全不同:

存储形态示例处理方法
真日期格式2024-01-15直接转成datetime对象
字符串格式20240115用format="%Y%m%d"解析
数字序列45277从1899-12-30起累加天数

数字序列在Pandas里不自动识别,读出来是一列整数。解析方法为:

import pandas as pd df["日期"] = pd.to_datetime("1899-12-30") + pd.to_timedelta(df["日期数值"], unit="D")

为什么是从1899年12月30日而不是1900年1月1日?这源于历史软件日期序列的起点规则。1980年以后的数据不会碰到1900年闰年bug的影响,所以直接用这个基点转换是安全的。

3. 这套数据在真实业务中值钱的应用方向

3.1 农业:霜冻界定、无霜期和冷害监测

农业生产里,最低气温比平均气温更能定义霜冻风险。比如某些果树在花期遇到-2℃以下的低温就可能造成减产;春季最后一次霜冻日推迟,播种和定植计划就要跟着调整。

用逐日最低气温数据可以计算县域无霜期长度:

df["霜冻日"] = (df["最低气温"] <= 0).astype(int) # 每年最后一次霜冻日 last_frost = df[df["霜冻日"] == 1].groupby(["年份", "行政区划代码"])["日期"].max() # 每年最早一次霜冻日 first_frost = df[df["霜冻日"] == 1].groupby(["年份", "行政区划代码"])["日期"].min()

这样的指数比单看某一天的低温值更有业务指导性。搭配产量历史数据,就能评估某个县域霜冻灾害年景。

3.2 能源:供暖度日数的简化估算

能源调度通常关注供暖度日数(HDD),标准定义依赖日平均气温。如果数据包没有平均气温,只有最低气温,可以拿最低气温做简化近似,比如设定一个低温阈值,把低于阈值的部分累加作为冷量强度指标。

我不建议照搬标准公式,因为用最低温代替平均温会系统性低估实际供暖需求。更合理的做法是把最低气温和当地负荷历史数据做回归,自己标定参数。逐日数据的好处就是样本量大,一年365个点,足够你做一个像样的相关性分析,不必依赖别人给你的固定系数。

3.3 公共健康与交通:寒潮持续事件识别

健康风险研究里,极端低温的持续天数比单日最低温更重要。连续三天以上、日最低气温大幅低于当地多年同期均值,往往对应着心血管疾病风险上升和道路结冰事故增加。

用这套数据可以统计每个县级区域每年“低温事件”发生的次数、平均持续时间和最早开始日期。加上行政区划经纬度,还能判断风险的空间集聚特征,为应急预案制定提供基础图层。

4. 数据清洗过程中最容易踩的四个坑

4.1 乱码不是文件损坏,而是DBF编码识别失败

排查链路应该是:现象是属性表中文乱码;第一步检查是否所有字符列都乱码,还是只有部分列;第二步打开GIS数据源编码选项,尝试GBK、GB18030、UTF-8三种;第三步如果仍有问题,检查.cpg文件,或直接用文本工具查看.dbf开头的字符集标记。乱码解决后,建议把数据导出为GeoPackage格式,后续不再受编码困扰。

4.2 数字“0”到底是真零度还是缺测标记

很多气象数据用特殊值标记缺测,常见的有9999、-9999、999999。但更低级的陷阱是“0”既可能是真实的0.0℃,也可能是无效值。我的经验是结合日期和空间位置一起判断:盛夏时节内陆多个县集体出现最低温0℃,基本是异常;冬天某高海拔县出现0℃,可能完全正常。

清洗时可以先把超出合理物理范围的值统一转为NaN,再统计缺失率。比如摄氏度单位下,可以把小于-60℃和大于50℃的过滤掉。

df["最低气温"] = pd.to_numeric(df["最低气温"], errors="coerce") df.loc[~df["最低气温"].between(-60, 50), "最低气温"] = None

4.3 按名称合并时行数暴涨或者大量缺失

用县名做关联是非常顺手但非常危险的操作。同一个县名在不同年份可能对应不同代码,不同县也可能有类似名称。合并之后行数异常增多,多半是连接字段存在重复;大量缺失,则可能是代码或名称存在前导零丢失。

规范的字段类型必须一致并统一为六位字符串:

df["行政区划代码"] = df["行政区划代码"].astype(str).str.zfill(6)

不要存成数字,否则前导零消失后,代码就错位了。

4.4 行政区划变动导致的历史序列不连续

这里不细说具体某个地方的变化,但从全国尺度看,过去几十年的行政区划调整频率相当高。你手上这份数据的“行政区划代码”对应的可能是2020年或2024年的行政区划版本,而你要研究的年份可能还在旧版本里。

建议做法分三步:第一,对研究期内的行政区划代码做去重和变化检测;第二,如果代码变化频繁,尝试用“年份+区域映射表”做历史版本归并;第三,如果你只需要制图分析,不必强行把历史数据统一到最新边界,可以用“当时的行政区划”出历史图,用“最新边界”出现状图,两个图不要混用。

5. 实操演示:把特定日最低气温挂到县级Shapefile上

5.1 第一步:读取并清洗Excel数据

假设你的文件名是“全国县级逐日最低气温_2024.xlsx”,读取时注意指定代码列是字符串。

import pandas as pd raw = pd.read_excel( "全国县级逐日最低气温_2024.xlsx", dtype={"行政区划代码": str} ) raw["日期"] = pd.to_datetime(raw["日期"].astype(str), format="%Y%m%d", errors="coerce") raw["最低气温"] = pd.to_numeric(raw["最低气温"], errors="coerce") # 过滤不可信极值 raw = raw[raw["最低气温"].between(-60, 50)] # 筛选出你要出图的那一天 target = raw[raw["日期"] == "2024-01-15"].copy() target["行政区划代码"] = target["行政区划代码"].str.zfill(6)

如果字段名不同,根据实际文件修改列名即可。读取后别急着合并,先打印target.head()看一眼。

5.2 第二步:用行政区划代码关联空间图层

用GeoPandas读取县级行政区Shapefile,同样把代码列处理成六位字符串。

import geopandas as gpd gdf = gpd.read_file("县级行政区划.shp", encoding="utf-8") gdf["行政区划代码"] = gdf["行政区划代码"].astype(str).str.zfill(6) merged = gdf.merge( target[["行政区划代码", "最低气温"]], on="行政区划代码", how="left" ) print(merged["最低气温"].isna().sum()) # 查看未匹配上的县

这一步如果大量缺失,首要检查不是几何问题,而是代码是否都是字符串且位数一致。也可以顺便看看目标文件里是否有重复代码,用target["行政区划代码"].duplicated().sum()检查。

5.3 第三步:导出与渲染

合并完成后,直接导出为GeoPackage,避免再把Shapefile那一堆小文件拷来拷去。

merged = merged.to_crs("EPSG:4326") merged.to_file("2024-01-15全国县级最低气温.gpkg", driver="GPKG")

后续在QGIS里打开这个GeoPackage,按“最低气温”字段做分级设色即可。配色建议用蓝色系代表低温、红色系代表高温,这样图面语义更直观。别忘在出图标题里写上具体日期,因为逐日数据一旦混用日期,很容易出“图上日期和文件名不一致”的低级错误。

6. 拿到数据后建议先做的四项验证

6.1 用一场你记得住的强降温过程来复核

不论数据生产方说自己的数据多么准确,我都建议先找一次自己经历过的、印象深刻的强降温过程做复核。选几个你熟悉区域,看那几天最低气温的变化趋势是否符合记忆和常识。如果趋势对,说明数据的时间连续性基本可靠;如果完全对不上,就要怀疑日期列是不是存在整体偏移或时区问题。

6.2 绘制年度最低温序列,识别整体异常

把全国或研究区域每年最低温度取出来画一条折线,正常情况下不会出现毫无原因的骤变。异常的骤升骤降往往对应数据处理错误,比如某一年没有除以10、某一年缺失值没有被正确识别。

检查代码:

year_min = raw.groupby(raw["日期"].dt.year)["最低气温"].min() print(year_min)

看到这种汇总图,再回到细节里查找具体日期,比直接全表搜索更高效。

6.3 空间相邻检查:边界两侧应当平滑过渡

把某一天的县级最低气温渲染到地图上,肉眼观察相邻县域之间有没有大跨度跳变。自然情况下,平地区域相邻县域温差通常不会特别夸张;如果一块区域被一条明显“撕裂”的边界分为左右两半,大概率是行政区划代码错位或某个文件字段顺序不对。

这种检查不能只看最高最低值,要看空间格局是否“讲得通”。地形复杂的山区例外,高差会带来明显温差,这时要结合DEM判断。

6.4 缺失率统计与插值决策

逐日数据经历多年整理,几乎不可能零缺失。对每个年份、每个月统计缺失率,会直接影响后续建模时是否要做插值。

raw["月份"] = raw["日期"].dt.month missing = raw[raw["最低气温"].isna()].groupby(["日期"]).size() missing.to_csv("缺失日期统计.csv", encoding="utf-8-sig")

如果缺失只集中在少数几天,通常可以直接剔除;如果某个月成片缺失,可能要考虑线性插值、空间插值,或者使用上一级行政区域均值做填充。填不填充没有绝对标准,但一定要在分析报告里写清楚,不然别人复现时会得出完全不同结果。

最后再分享一个小技巧:这类上传分享的数据文件往往没有附带非常详尽的字段说明,花半小时做一个压缩包内文件清点,再按本文的思路做一遍字段和单位检查,远比直接拖进软件跑分析划算。尤其在多人协作时,把“单位是摄氏度还是0.1℃”“日期格式是什么”“行政区划版本是哪一年”这三条写清楚,整个项目的返工率能降下一大截。

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

Python开发者必会的Linux命令:从项目初始化到线上排障

1. 开篇&#xff1a;为什么Python开发者离不开Linux命令 说实话&#xff0c;我接触过不少Python开发者&#xff0c;有人写Python两年了&#xff0c;还是习惯在Windows上做开发&#xff0c;一提到Linux就有点抵触。但真正开始部署项目、处理线上问题之后&#xff0c;几乎所有人都…

作者头像 李华
网站建设 2026/10/11 16:49:36

CNN卷积神经网络实战:MNIST手写识别从零到99%准确率

简介&#xff1a;面向深度学习初学者、TensorFlow入门者以及需要完成图像识别课程设计的读者&#xff0c;这份资源以经典MNIST手写数字识别为切入点&#xff0c;用一个紧凑的CNN实现展示从数据输入、卷积层、池化层、全连接层到softmax分类的完整流程。zip压缩包内共2个Python脚…

作者头像 李华
网站建设 2026/10/11 16:48:57

计算机网络物理层详解:从编码、带宽到光纤与信道复用

很多人做网络排障时有个惯性&#xff1a;先看IP、再查网关、最后才想起物理层。可真正干过几年网络运维的人都知道&#xff0c;百分之七十的“灵异问题”都出在物理层——网线没打对、光纤弯折过大、设备端口协商失败&#xff0c;这些才是让业务断断续续的元凶。这一章讲的物理…

作者头像 李华
网站建设 2026/10/11 16:48:13

AI原生的MDM平台到底有多强大?

很多集团企业在主数据治理上反复踩坑&#xff1a;投入预算上线 MDM 平台&#xff0c;但长期依赖 IT 人员维护&#xff0c;客商、物料主数据重复问题依然层出不穷&#xff1b;业务人员觉得操作复杂不愿使用&#xff0c;主数据标准更新滞后&#xff0c;跨系统口径不一致问题难以根…

作者头像 李华
网站建设 2026/10/11 16:46:40

RAID 0/1/5/6/10全解析:选型、建阵列与故障恢复实战指南

如果你跟我一样整天和存储设备打交道&#xff0c;那“RAID 0/1/5/6/10”这几个数字绝对不陌生。很多人刚接触服务器时&#xff0c;第一课就是背RAID级别的概念&#xff1a;0要性能&#xff0c;1要安全&#xff0c;5折中&#xff0c;10又安全又性能。可真到了选型、建阵列、坏盘…

作者头像 李华
网站建设 2026/10/11 16:45:33

Flutter鸿蒙响应式布局实战:MediaQuery与LayoutBuilder适配多端屏幕

户外广告设计师老周最近接了台鸿蒙平板的适配需求&#xff0c;发现原本在手机上表现良好的Flutter页面到了平板上不是拉伸变形就是空白留边。他跟我说了一句话让我印象很深&#xff1a;“Flutter不是号称一套代码多端运行吗&#xff0c;怎么换个屏幕就现原形了&#xff1f;”我…

作者头像 李华