简介本资源为基于NCDC原始观测处理得到的2020年中国年均气温数据集面向气象、地理信息、生态环境及城市规划等方向的研究人员与GIS学习者可用于全国尺度气温空间分布分析、气候区划、模型验证与制图出图等场景。压缩包共10个文件约100KB包含一份年均气温栅格tif及其金字塔ovr、坐标tfw与aux.xml元数据以及一套站点矢量数据shp、shx、dbf、prj、sbn、sbx栅格与站点点层配套便于直接加载到ArcGIS中进行空间插值对比、符号化展示与属性查询。目前已有1637人学习下载说明该数据在同类资源中具备一定参考价值。读者可据此快速复现2020年全国年均气温的空间格局结合站点属性开展区域差异分析或作为气候相关课题的基础底图与验证样本省去自行处理原始NCDC数据的繁琐步骤。1. 从一份“点面”气温数据说起为什么年均温不能只看一个数拿到「中国2020年均气温数据点加栅格.zip」这个标题很多人第一反应是不就是一份气温数据吗打开看看哪里热哪里冷就完了。但真正做过气候分析、农业区划、城市热岛研究的人会告诉你年均气温这件事从来不是“一个城市一个数”那么简单。站点观测值精确到具体经纬度却稀疏且分布不均栅格数据铺满整个国土却带着插值带来的平滑误差。把两者放进同一个分析流程才是这份数据真正的价值所在。这份数据面向的人群很明确做气象、地理、生态、农业、城市规划的从业者以及需要把气温作为自变量跑模型的数据科学工作者。它能解决的核心问题是——当你需要“2020年这一年、中国任意一个位置、年均气温大概是多少”时站点给你真值锚点栅格给你空间连续性。适合谁适合那些不满足于调用一个在线接口拿个城市均值而是想自己掌控数据、做空间统计、做可视化、做后续建模的人。接下来我会把这份数据的结构、读取、点栅格匹配、常见翻车点一层层拆开讲清楚。2. 站点与栅格到底差在哪先搞懂两类数据的脾气2.1 站点数据真值锚点但别指望它铺满地图站点观测数据本质上是气象站用温度传感器在固定位置、固定高度测出来的日均值再按年求平均。它的优点是“真”——没有插值、没有平滑代表的是那个点上的实际大气状态。缺点是空间代表性有限一个站点代表的范围取决于下垫面、地形和气候带平原地区可能几十公里都差不多山区可能隔一条沟就差好几度。从数据格式看站点数据常见的是 CSV 或 Excel字段一般包括站号、经度、纬度、海拔、年均温。你拿到手第一件事不是画图而是检查三件事经纬度是度还是度分秒、有没有缺测标记比如 9999 或 -999、站点数量在 2020 年是否明显少于往年。我一般会先跑一遍描述性统计看均值和分位数是否合理比如中国年均温大致在 -5℃ 到 25℃ 之间如果出现 60℃ 或 -80℃那基本是缺测值没处理。2.2 栅格数据空间连续但每一格都是“算出来的”栅格数据是把中国切成一个个规则网格每个格子给一个年均温值。它通常由站点数据经过空间插值反距离加权、克里金、样条函数等生成也可能融合了遥感地表温度。优点是好看、好用、能直接做空间运算缺点是它不是观测值而是模型输出。在站点密集的东部栅格值可信度较高在站点稀疏的西部高原栅格值可能偏离真实情况好几度。栅格文件常见格式是 GeoTIFF 或 NetCDF。GeoTIFF 带地理变换参数能直接和矢量边界叠加NetCDF 更适合多维数据比如同时有经度、纬度、时间三个维度。你拿到栅格后第一件事是确认坐标系是 WGS84 经纬度还是投影坐标系比如 Albers 等面积投影。如果坐标系搞错后面所有空间匹配都会错位这是血泪经验里最常见的一类翻车。2.3 点加栅格不是简单叠加而是互相验证把站点和栅格放在一起最直接的用法是“提取”用站点经纬度去栅格上取值然后和站点实测值比较。这一步能帮你判断栅格在你研究区的精度。如果某站点实测 15℃栅格提取出来 22℃那要么是插值问题要么是坐标系没对齐要么是站点海拔和栅格平均海拔差异太大。更深一层的用法是“融合”以站点为真值对栅格做偏差校正生成一套更准的格点数据。常见做法是计算每个站点的残差实测减栅格再对残差做空间插值最后把插值后的残差加回原栅格。这样既保留了栅格的空间连续性又拉近了站点附近的真值。这一步在农业气候区划里非常实用因为作物模型对温度偏差很敏感。3. 用 Python 把点与栅格读进来最小可跑通流程3.1 环境准备与依赖安装处理这份数据我一般用 Python核心库就几个pandas 读站点表格rasterio 读栅格geopandas 做空间操作numpy 做数值计算。如果你还没装用 conda 或 pip 都行。下面命令假设你用的是 conda 环境避免和系统包冲突。conda create -n temp2020 python3.10 conda activate temp2020 conda install -c conda-forge pandas rasterio geopandas numpy matplotlib逻辑说明单独建环境是为了避免 rasterio 和 gdal 的版本冲突这两个库对底层依赖很挑。参数上python 3.10 是目前兼容性较好的版本conda-forge 渠道的 rasterio 预编译包在 Windows 和 Linux 上都比较稳。装完后可以在命令行输入python -c import rasterio; print(rasterio.__version__)验证。3.2 读取站点 CSV 并做第一轮清洗假设站点文件叫stations_2020.csv字段有station_id, lon, lat, elev, temp_annual。下面代码做三件事读文件、把缺测值替换成 NaN、打印基本统计。import pandas as pd import numpy as np # 读取站点数据注意编码可能是 gbk 或 utf-8 df pd.read_csv(stations_2020.csv, encodingutf-8) # 常见缺测标记替换 df df.replace([9999, -9999, 999.9], np.nan) # 只保留有经纬度和温度的记录 df df.dropna(subset[lon, lat, temp_annual]) # 基本检查 print(站点数, len(df)) print(经度范围, df[lon].min(), df[lon].max()) print(纬度范围, df[lat].min(), df[lat].max()) print(年均温统计\n, df[temp_annual].describe())逻辑说明replace那一步是关键很多气象数据用 9999 表示缺测不处理会直接把均值拉爆。dropna只针对关键字段避免误删有温度但海拔缺失的站点。打印经纬度范围是为了确认数据覆盖中国大致范围经度约 73-135纬度约 18-54如果范围不对可能是投影坐标没转成经纬度。参数说明encoding根据实际文件调整如果报 UnicodeDecodeError 就换gbk。temp_annual字段名以实际文件为准可能是中文或别的英文名。3.3 读取栅格并查看元信息栅格文件假设叫china_temp_2020.tif。下面代码读取并打印关键元数据。import rasterio with rasterio.open(china_temp_2020.tif) as src: print(坐标系, src.crs) print(栅格大小, src.width, x, src.height) print(波段数, src.count) print(地理范围, src.bounds) print(像元大小, src.res) data src.read(1) # 读第一个波段 print(数据形状, data.shape) print(无效值, src.nodata)逻辑说明src.crs告诉你坐标系如果是 EPSG:4326 就是经纬度如果是其他投影后面提取前需要统一。src.bounds给出栅格覆盖的经纬度或投影范围和站点范围对比能发现是否错位。src.nodata是无效值标记读进来后要把它设成 NaN否则参与计算会出错。参数说明src.read(1)读第一个波段如果栅格有多个波段比如 12 个月需要按需读取。res是像元分辨率常见有 0.01 度、0.05 度、1 公里等分辨率越高文件越大。3.4 用站点坐标提取栅格值这一步是点加栅格的核心操作。用 rasterio 的sample或index方法把站点经纬度转成栅格行列号再取值。import rasterio import numpy as np # 假设 df 已经清洗好有 lon 和 lat 列 coords [(x, y) for x, y in zip(df[lon], df[lat])] with rasterio.open(china_temp_2020.tif) as src: # 检查站点坐标系是否和栅格一致这里假设都是 EPSG:4326 sampled list(src.sample(coords)) df[temp_grid] [v[0] if v[0] ! src.nodata else np.nan for v in sampled] # 计算偏差 df[diff] df[temp_annual] - df[temp_grid] print(df[[station_id, temp_annual, temp_grid, diff]].head()) print(偏差统计\n, df[diff].describe())逻辑说明src.sample接收经纬度坐标列表返回每个点所在像元的值。如果站点坐标系和栅格不一致需要先用 pyproj 或 geopandas 转换。diff是实测减栅格正值表示栅格低估负值表示高估。偏差统计的均值接近 0 说明整体无偏标准差反映插值误差大小。参数说明src.nodata判断无效值如果栅格没有定义 nodata需要手动指定一个极端值。sample默认用最近邻如果要用双线性插值可以改用src.sample(coords, indexes1)配合其他库。4. 避坑与排查点栅格匹配中最容易翻车的五件事4.1 现象提取出来的栅格值全是 NaN原因站点经纬度顺序写反了或者坐标系不一致。比如站点是投影坐标单位米栅格是经纬度单位度sample找不到对应像元就返回 nodata。解决先打印站点前几行经纬度确认数值范围。如果经度大于 180 或纬度大于 90基本是投影坐标。用 geopandas 转成 EPSG:4326 再提取。import geopandas as gpd from shapely.geometry import Point gdf gpd.GeoDataFrame(df, geometry[Point(x, y) for x, y in zip(df[lon], df[lat])], crsEPSG:32650) gdf gdf.to_crs(EPSG:4326) df[lon] gdf.geometry.x df[lat] gdf.geometry.y4.2 现象偏差大得离谱动辄十几度原因站点海拔和栅格平均海拔差异大。气温随海拔升高而降低递减率约 0.6℃/100 米。如果站点在山上栅格代表的是周围低地提取值自然偏高。解决做海拔校正。用站点海拔和栅格海拔如果有计算差值按递减率修正。没有栅格海拔就只分析低海拔站点或把海拔作为协变量做回归。4.3 现象东部站点匹配好西部站点偏差大原因西部站点稀疏插值栅格在那边基本靠外推可信度低。这不是代码问题是数据本身的空间代表性限制。解决分区域统计偏差西部单独看。如果做全国分析建议对西部结果加不确定性说明或者只用站点数据做西部分析。4.4 现象栅格读进来全是 0 或负数原因栅格存储时做了缩放比如真实温度是 15.3℃存成整数 153需要乘以 0.1。或者用了偏移量。解决查看栅格的元数据里的scale和offset读完后做data * scale offset。rasterio 可以用src.read(1, maskedTrue)自动处理部分情况。4.5 现象内存爆了读大栅格直接卡死原因全国高分辨率栅格可能几个 GB一次性读进内存扛不住。解决用窗口读取只读研究区范围。或者用src.read(1, out_shape(src.height//2, src.width//2))降采样。做点提取时sample本身是流式的不会全读但如果你先read再索引就会爆。5. 从匹配到应用偏差校正与空间制图的一个具体技巧5.1 用站点残差做简易偏差校正如果你想让栅格在站点附近更准可以做一个轻量校正计算每个站点的diff对diff做反距离加权插值到整个栅格然后加回原栅格。下面是一个简化实现用 scipy 的griddata。import numpy as np import rasterio from scipy.interpolate import griddata # 假设 df 有 lon, lat, diff points df[[lon, lat]].values values df[diff].values with rasterio.open(china_temp_2020.tif) as src: data src.read(1).astype(float) data[data src.nodata] np.nan transform src.transform height, width data.shape # 生成栅格中心点经纬度 cols, rows np.meshgrid(np.arange(width), np.arange(height)) xs, ys rasterio.transform.xy(transform, rows, cols) xs np.array(xs).reshape(height, width) ys np.array(ys).reshape(height, width) # 插值残差 grid_diff griddata(points, values, (xs, ys), methodlinear) # 校正 corrected data grid_diff # 保存 with rasterio.open(china_temp_2020_corrected.tif, w, driverGTiff, heightheight, widthwidth, count1, dtypecorrected.dtype, crssrc.crs, transformtransform, nodatanp.nan) as dst: dst.write(corrected, 1)逻辑说明griddata用站点残差插值到每个栅格中心methodlinear比最近邻平滑但在站点稀疏区可能产生 NaN可以改用nearest填补。校正后的栅格在站点附近更接近实测但远离站点处仍依赖原插值质量。参数说明rasterio.transform.xy把行列号转成经纬度注意行列顺序。保存时nodatanp.nan需要栅格支持浮点如果原栅格是整数要改 dtype 为 float32。5.2 用 GeoPandas 快速出图验证校正完别急着用先画个图看看空间格局是否合理。下面代码用站点和栅格叠加出图。import matplotlib.pyplot as plt import geopandas as gpd from shapely.geometry import Point fig, ax plt.subplots(figsize(10, 8)) # 栅格 with rasterio.open(china_temp_2020_corrected.tif) as src: data src.read(1) ax.imshow(data, cmapRdYlBu_r, extent[src.bounds.left, src.bounds.right, src.bounds.bottom, src.bounds.top]) # 站点 gdf gpd.GeoDataFrame(df, geometry[Point(x, y) for x, y in zip(df[lon], df[lat])]) gdf.plot(axax, columntemp_annual, cmapRdYlBu_r, markersize5, legendTrue) ax.set_title(2020年中国年均温站点与校正栅格) plt.show()逻辑说明imshow的extent用栅格边界保证和站点对齐。站点用column着色和栅格同一色带肉眼就能看出哪里偏差大。如果站点颜色和底下栅格明显不搭说明校正没起效或坐标系还有问题。参数说明cmapRdYlBu_r是气温常用色带红暖蓝冷。markersize根据站点数量调整太多就调小。5.3 我踩过的坑与固定习惯做了几年气温数据我最大的教训是永远不要假设坐标系是对的。有一次帮人做分析站点是经纬度栅格是 Albers我没检查直接提取结果所有站点都落在栅格外返回全 NaN排查了一下午才发现是投影问题。从那以后我固定会在读取后打印src.crs和站点经纬度范围确认一致再往下走。第二个习惯是先做小样本验证。不要一上来就跑全国先选一个省或一个气候区把流程跑通看偏差统计合理了再放大。这样出问题容易定位也省时间。第三个习惯是保存中间结果。清洗后的站点、提取后的表格、校正后的栅格都单独存一份。后面调参或换方法时不用从头再来。这份「中国2020年均气温数据点加栅格.zip」的价值不在于数据本身多稀有而在于它逼着你把点与面的关系想清楚。把这个流程走一遍以后拿到任何年份、任何区域的气温数据你都能自己搭出一套可复现的分析链路。希望帮到你。本文还有配套的精品资源点击获取