做农险精算、能源负荷分析或者城市规划的朋友应该都有这种感受真正要评估一次冷冬、一场冻害或者推演采暖负荷的时候需要的往往不是某年某月的平均气温而是落到每一个省市县行政单元、每一自然日的最低气温。最近我整理完一套2005—2025年全国省市县三级的逐日最低气温数据按Excel和Shp两种格式同时提供。这篇文章不打算只罗列我有什么数据而是想把数据结构怎么设计的、拿到手怎么处理、空间上怎么用、以及最容易忽略的几个边界问题一次讲透。无论你是刚接触这类数据的学生还是已经在用ArcGIS、QGIS做日常分析的一线从业者按自己的基础挑着看就行我说的每一步都是实际跑过的。1. 为什么我从海量气象原始记录里整理了这套逐日最低气温数据1.1 先想清楚数据要服务哪些场景先说结论这套数据不是给气象台做预报用的而是给下游应用做评估和决策用的。我在整理之前梳理过一遍实际需求基本集中在四类场景上。农业是最直接的。冬季越冬作物评估、果树冻害保险理赔、大棚低温预警都需要知道某一档低温在某一个县持续了多少天。比如茶叶种植区最怕的是春季霜冻光看日平均气温偏差很难判断因为也许整体偏暖但某一天凌晨的低温直接把新芽打掉了。逐日最低气温配合物候期窗口才能真正落地。能源行业也离不开最低气温。城市采暖负荷和室外日最低气温的相关系数非常高尤其北方几个省份一到寒潮过程负荷直接拉满。做负荷预测模型时最低气温是比平均气温更敏感的输入变量。建筑行业的需求更偏设计重现期。比如围护结构热工设计、采暖通风设计本身就需要逐年逐日的极端低温序列用来推算所谓历年不保证日数或冷冬重现期。没有连续多年的逐日最低气温这些参数只能靠估算。还有一类是低温天气指数保险。这几年各地推的天气指数保险理赔条件经常写某县某日内最低气温低于-4℃触发赔付。做这类产品必须用县级行政单元的逐日序列而不是气象站单点数据。1.2 最低气温这条指标的独特性你可能想问为什么非要最低气温直接用平均气温不行吗我的经验是平均气温会把极端信息稀释掉。举个例子某年冬天某县白天温度接近常年但连续三个清晨最低气温跌破-10℃对露天蔬菜、多年生果树来说这三天就是致命的。平均气温序列里这三个异常点基本上看不出来但逐日最低气温序列里它们就是明显的谷值是做极端事件分析和灾害评估时最有信息量的部分。另外从数据整理角度看最低气温也比平均气温更容易做质控。气象站观测记录里日最低气温出现的时间相对规律通常在后半夜到清晨受太阳辐射影响小插值和订正的逻辑更清晰。所以这套数据在整理时我选择以最低气温为核心变量而不是做一套全要素的大杂烩保证每条记录的可靠性。2005到2025年这个时间窗也很有意义。21年的时间跨度足够覆盖近两轮冷暖波动既能支撑气候态统计通常要求至少30年但21年在很多工程初设估算里已经是可用序列又能让十年一遇级别的极值推算有真实样本做校准不会只依赖零散的多年平均值。2. 数据格式与字段设计Excel和Shp里分别装了什么2.1 Excel文件的组织方式与字段约定先说Excel。很多人拿到逐日数据的第一反应是一天一行这个直觉要分情况看。全国县级一共2800多个县级行政单元如果按省—市—县—日期—最低气温这种长表结构做2005到2025年约7660天总行数会突破2000万行。Excel单表上限是104万行肯定装不下。所以我在整理时采用了分层文件结构最常用的是省级和市级的长表每个文件一行表示某省市某日的最低气温配合行政区划代码使用Excel可以直接处理县级数据按年份拆分文件每年一个Excel工作簿每个工作簿仍然是长表结构单文件控制在一个县级行政单元数量乘以当年天数左右大约一百万行上下刚好压在Excel极限附近同时提供一份县级宽表版本每行是一个县每一列是某一天的最低气温列名就是日期方便做相关分析、求极值和绘制热力图。字段设计上我统一保留了这些列行政区划代码使用国标6位或12位代码这是关联数据的唯一主键省名、市名、县名作为展示字段方便肉眼识别日期统一为YYYY-MM-DD文本或日期格式最低气温统一单位摄氏度保留一位小数数据来源标识区分站点观测直接值、插值订正值和推算值。缺失值我约定用-9999标注而不是留空。原因很简单Excel的透视表和ArcGIS的属性表关联时空值经常会参与计算或者被当作0处理-9999至少在筛选的时候可以一眼识别。2.2 Shp文件的边界底图与属性表设计Shp格式是空间数据的老牌格式一个完整的Shapefile由.shp几何、.shx索引、.dbf属性、.prj投影信息等文件构成。经常有人只拷贝了.shp就抱怨打开失败其实缺一个都不行。我提供的Shp数据里边界底图是按省、市、县三级分别输出的坐标系统一使用CGCS2000或WGS84方便和大多数公开数据叠加。属性表设计上和Excel保持一致的原则行政区划代码、省名、市名、县名作为基础字段另外放入该行政单元的多年最低气温统计指标比如历年最低气温、多年平均最低气温、极端低值出现日期等。逐日明细不放进Shp属性表否则会变成7660多个字段实际没法用。正确用法是把Shp当成空间索引用行政区划代码和Excel里的逐日数据做关联。2.3 数据量估算与文件切分逻辑我列一组估算数供你参考。全国省级行政区划约31个不含港澳台数据时地市级约333个县级约2843个2005到2025年跨越21年包含闰年按年均365.25天估算总天数约7665天。省级长表31 × 7665 ≈ 23.7万行Excel完全无压力地市级长表333 × 7665 ≈ 255万行需要拆成两个文件或者用Access、数据库处理县级长表2843 × 7665 ≈ 2178万行必须按年拆分或直接入库县级宽表2843行 × 约7667列行数没问题但列数逼近Excel上限16384列一半操作也不算方便主要用于程序化分析。所以如果你拿到手发现县级Excel是按年拆分的不是我偷懒而是Excel本身的物理限制逼出来的。处理全县级全时间序列时建议直接用Python或关系型数据库后面我会给具体操作。3. Excel端的实操筛选、统计和绕开性能瓶颈3.1 打开多行表之前的准备工作如果你只关心某几个省或者某几年建议先不要双击就硬开全量大文件。我的习惯是第一步用文本编辑器或Python先看一眼文件结构和缺失值情况别急着进Excel。第二打开Excel后立刻按CtrlT把区域转成表格这样后续筛选、透视表、公式引用都会自动扩展范围。这一步看着不起眼但在两千多行甚至几十万行数据里能省掉大量公式没拉到新行的麻烦。第三把日期列改成真正的日期格式而不是文本。这个很关键不然你用SUMIFS按日期筛选时等值匹配还凑合日期区间匹配就全乱套了。如果只是想看某一天全国各地的最低气温分布最快的操作是选中整列后加筛选条件或者直接对日期列设筛选再按数值排序。想快速定位极端低值比如低于-20℃的记录在最低气温列上做数字筛选选择小于 -20即可不用写任何公式。3.2 高频操作多条件筛选、SUMIFS、快速定位Excel里处理这类逐日数据最高频的三个函数我推荐掌握。第一个是SUMIFS。它不仅能求和也能当带条件计数用。比如统计某县2015年冬季最低气温低于-5℃的天数可以写SUMIFS(数据!最低气温列, 数据!县级代码列, A县代码, 数据!日期列, 2015-12-01, 数据!日期列, 2016-02-29)注意日期在SUMIFS里比较时要保证条件和数据列的日期类型一致不然经常返回0。第二个是AVERAGEIFS用来算某条件下平均最低气温功能上和SUMIFS一致只是返回均值。第三个是快速定位。不光是CtrlF查找也建议用定位条件F5或CtrlG里的空值选项一键选中整列里所有缺失单元格然后统一批量处理——例如填充-9999。这个操作对手工检查数据质量非常有效。顺便说一个Excel里容易翻车的点公式下拉失效。很多时候是Excel选项里自动计算被关了或者单元格被设成了文本格式。解决办法是到公式选项卡里打开自动计算再检查目标列格式。如果是某个文件单独出问题检查是否加载了第三方加载项有些统计类加载项会干扰单元格计算这也是加载项被禁用后反而正常的常见原因。3.3 用Python绕开Excel做批处理数据量一旦上去Excel本身再怎么优化也是杯水车薪。2178万行的县级长表你可以用pandas读进来速度取决于内存但至少不会像Excel那样卡死。import pandas as pd df pd.read_csv(daily_tmin_2020.csv, encodingutf-8) df[date] pd.to_datetime(df[date]) # 筛选某县某时段 sub df[(df[county_code] 110101) (df[date] 2020-01-01)] # 求该县当年最低气温及出现日期 idx sub[tmin].idxmin() print(sub.loc[idx])把结果写回Excel时我建议用openpyxl而不是直接to_excel特别是你要同时保留多个工作表、设置列宽和格式时from openpyxl import Workbook wb Workbook() ws wb.active ws.append([行政区划代码, 日期, 最低气温]) for row in result.itertuples(indexFalse): ws.append(list(row)) wb.save(result.xlsx)另外Excel里很多文本查找的场景比如要在几十万行里找包含某个字符的地名我会在pandas里用str.contains先处理而不是在Excel里CtrlF一页页翻。正则表达式也是一样Excel的REGEXEXTRACT函数在Office 365里能用但速度完全不能和Python比。4. Shp端的空间操作从属性关联到三维可视化4.1 把Excel日值挂到行政区划面上拿到Shp底图后最容易的需求就是在地图上给某一天的低温涂色。这里有个合作分工Shp提供面和位置Excel提供逐日数值。关联之前先确认两边的主键字段完全一致通常用6位县级代码或12位村级统计用代码。在ArcGIS里操作步骤是先打开Shp图层右键选择连接和关联→连接然后在弹窗里选择基于某字段的连接输入源选择Excel文件关键字段选行政区划代码目标图层字段也选行政区划代码。这里最容易踩的坑是字段类型不匹配——Excel里的代码列如果是数字格式Shp里是文本格式会导致连接后大量空值。解决方法是把两边的代码列都转成文本或者统一补零成等长字符串。连接完成后按最低气温字段设置分级符号化即可。比如将某日数据分成以下几档温度区间含义建议配色高于0℃无冻害风险绿-5℃到0℃轻霜冻风险黄-10℃到-5℃明显低温橙-15℃到-10℃严重低温红低于-15℃极端低温深红配色层级建议按绿色到深红的渐变不用分太多级否则小比例尺下很难看出趋势。4.2 叠加分析地形、DEM与气温的空间关系最低气温很受地形影响。同样是同一个县山区和河谷夜间温差可以超过5℃。所以做更精细分析时我会把Shp底图和高分辨率DEM叠加起来。常见做法是先把DEM栅格按县级行政单元做分区统计得到每个县的平均海拔、最低海拔或地形起伏度然后和最低气温序列做相关分析。ArcGIS里用分区统计工具QGIS里用Zonal Statistics插件操作都不复杂。如果你拿到的Shp文件没有海拔字段这个步骤正好能补上。从DEM提取Shp相关要素也是一个被问得很多的需求。比如你想提取某个县的坡向、坡度或者生成山谷线可以先把DEM转成等值线再用要素转面工具生成闭合多边形最后和县级Shp做叠加裁剪。注意提取出来的Shp不一定和气象数据一一对应它只是地形变量真正建模时还是要回到县级行政单元上合并。4.3 进阶方向shp转3dtiles与Web端展示这两年做三维可视化需求明显多了群里经常有人问shp怎么转3dtiles。我简单讲一下思路。3dtiles是Cesium用的三维瓦片格式适合在Web端加载海量矢量或倾斜模型。Shp转3dtiles的通用流程是先把Shp里的要素转换成三维几何也就是给每个面赋一个高度值然后按瓦片层级切分输出成带LOD的多级瓦片集合。常用工具包括CesiumLab、FME以及一些基于GDAL二次开发的命令行工具。操作上有几个提醒第一原Shp的坐标系必须和三维场景的坐标系对齐我一般先转成WGS84经纬度第二属性字段能精简就精简转瓦片后属性越多浏览器渲染越慢逐日气温这种大宽表强烈不建议塞进3dtiles应该留一个日期字段动态请求Excel或后台API的数据第三瓦片切分后有多个文件部署时需要正确的网络路径本地双击文件打开通常只能看到空场景。如果你只是想在本地快速预览三维效果先别急着转3dtiles用QGIS的三维视图加载Shp并设置高度拉伸几秒钟就能看到基础效果确认了再上Web端流程。5. 用这套数据前必须搞清楚的边界问题5.1 行政区划变更以代码为准而不是名称2005年到2025年这21年里我国行政区划发生过不少调整有些县改市有些市辖区重新划分有些地级市换了代码。名字可能没变但代码变了或者名字变了代码没变这些都是实际发生过的。如果你直接用2025年的边界底图去翻2005年的逐日数据会出现两种情况一是代码对不上连接后全是空值二是名称看着对但边界已经完全不同做区域统计时面积和人口基准就错了。我整理时做了一道保险所有年份的行政区划代码都按该数据年份当时的统计口径标注另附一份代码变更对照表。你自己使用时的原则是先查代码后看名称先确认边界基准年份再做跨期对比。不要拿2025年的Shp面去裁剪2020年以前的县均温度再做趋势这会混入边界变化的假信号。5.2 数据口径与数值核查最低气温看着简单定义却有讲究。气象上日最低气温有日界问题有的以当日20时到次日20时为一个日界有的按自然日零点到24点。两套定义在凌晨或深夜会出现1天左右的错位对于要求严格的灾害评估这点必须提前查清楚。拿到数据后我也建议做一次独立核查。最简单的方法选你所在城市把数据里的某县最低气温序列和当地气象站发布的实况数据对比一两个典型寒潮过程。数值差异如果在0.5℃以内一般是合格的差异超过2℃就要检查是不是行政区划错位、单位换算错误或者插值失真。另外注意单位约定如果原始表格写的是0.1℃作为单位你要除以10才是摄氏度这种错最容易出现在把数据从文本文件导入Excel时。5.3 常见误区Shp适合空间展示不宜直接当统计本底很多人习惯直接拿Shp属性表里的统计值做图表这个我要专门提醒一下。Shp的几何面代表的是行政边界但最低气温本质上来自气象站点或栅格插值行政面积大的县和面积小的县在同一个空间插值栅格里代表性完全不一样。一些县级单元面积上千平方公里区域内海拔落差可能有上千米一个县最低气温值背后掩盖的信息可能很多。我的建议是如果做县级横向比较看相对高低没问题如果做精确到村、到地块的应用至少要叠加高分辨率DEM和站点分布做局地订正不能把一个县的单一值硬套到乡镇。Shp在这里更像一个可视化容器而不是精确气象模型输出。这也解释了为什么我在组织数据时要单独提供Excel明细文件——空间上的统计汇总会丢信息逐日序列才是原始依据。数据整理到这一步我最想跟你分享的其实是两条经验一是用代码关联一切不要用汉字地名做连接键这是所有表格和空间数据能对上的前提二是永远保留一份最原始的长表数据宽表、统计表、Shp属性表都可以从长表重新生成但长表丢了原始信息就再也找不回来了。我最初整理时也偷懒过后来做冷冬回算时发现列顺序和日期对齐出了问题才知道源头数据不能图省事。这套2005—2025年的逐日最低气温数据如果你只是拿来做一两个县的小分析Excel筛选足够如果要做全国尺度的趋势和重现期老老实实上Python和数据库。数据本身只是原料能不能用好还是看你对行政边界、日期口径和单位约定这些小事有没有较真。
阅读完成 · 觉得有帮助?