数据使用说明
>
天机数据行政区域掩膜操作说明
Appearance
Appearance
本文档说明基于 cnmaps 包,对天机 NetCDF 格式模式预报数据按行政区域范围进行掩膜的操作方法。掩膜后将区域外的网格点标记为 NaN,区域内的网格点保留原始值,便于后续按行政区计算区域统计量(区域平均、区域最大/最小等)。
cnmaps 是一个基于高德地图数据、支持中国省市县三级行政区划边界获取与空间判定的 Python 包。
PyPI 地址:https://pypi.org/project/cnmaps/
GitHub 地址:https://github.com/cnmetlab/cnmaps
安装方式:
pip install cnmaps依赖说明:
cnmaps会自动安装cartopy、geopandas、shapely、numpy等必要依赖。
从天机官网(https://www.tjweather.com/Download)下载 NetCDF 文件。以 2 米气温数据为例:
| 项目 | 说明 |
|---|---|
| 文件 | 2026072900_t2mz_f001.nc |
| 变量 | t2mz(2 米气温,单位 K) |
| 维度 | time(1), lat(2400), lon(3200) |
| 覆盖范围 | 中国及周边区域 |
| 缺失值 | _FillValue = 1e+30 |
cnmaps 的 MapPolygon.make_mask_array(lons, lats) 方法返回一个布尔数组:
False:该网格点在行政区域内(保留)
True:该网格点在行政区域外(丢弃)
因此,应用掩膜的标准写法:
ds_masked = ds.where(~mask_array, np.nan)即:区域外网格置为 NaN,区域内网格保留原始值。
这样处理便于后续统计——用
np.nanmean()、np.nanmax()、np.nanmin()等nan系函数自动忽略区域外网格,直接得到区域内统计量。
import numpy as np
import xarray as xr
from cnmaps import get_adm_maps
# ── 1. 读入数据 ──
ds = xr.open_dataset('2026072900_t2mz_f001.nc')
lon = ds.lon.values
lat = ds.lat.values
# ── 2. 获取行政区边界并生成掩码 ──
polygons = get_adm_maps(level='省', province='河北省', only_polygon=True, wgs84=True)
# get_adm_maps 返回 list,通常只有一个元素
map_polygon = polygons[0]
mask = map_polygon.make_mask_array(lon, lat) # shape: (len(lat), len(lon))
# ── 3. 应用掩码(区域外 → NaN)──
ds_masked = ds.where(~mask, np.nan)
# ── 4. 区域统计 ──
t2m_mean = np.nanmean(ds_masked.t2mz.values) # 区域平均
t2m_max = np.nanmax(ds_masked.t2mz.values) # 区域最高
t2m_min = np.nanmin(ds_masked.t2mz.values) # 区域最低make_mask_array(lons, lats) 的入参为一维经纬度坐标数组,内部使用 np.meshgrid 构造二维网格后判定。返回的 mask 形状为 (len(lat), len(lon)),与 NetCDF 中 (lat, lon) 的空间维度顺序一致。
polygons = get_adm_maps(level='省', province='河北省', only_polygon=True, wgs84=True)
mask = polygons[0].make_mask_array(lon, lat)
ds_masked = ds.where(~mask, np.nan)
# 统计
print('河北平均气温:', np.nanmean(ds_masked.t2mz.values))polygons = get_adm_maps(level='市', province='河北省', city='唐山市',
only_polygon=True, wgs84=True)
mask = polygons[0].make_mask_array(lon, lat)
ds_masked = ds.where(~mask, np.nan)直辖市属于省级,获取时:
level='省', province='北京市'张家口市属于河北省,正确的省-市参数为province='河北省', city='张家口市'。省-市-县三级参数均需填写标准中文全称。
polygons = get_adm_maps(level='区县', province='河北省', city='唐山市',
district='曹妃甸区', only_polygon=True, wgs84=True)
mask = polygons[0].make_mask_array(lon, lat)
ds_masked = ds.where(~mask, np.nan)适用于"京津冀"等跨省联合区域。
# 分别获取各省掩码
polygons_bj = get_adm_maps(level='省', province='北京市', only_polygon=True, wgs84=True)
polygons_tj = get_adm_maps(level='省', province='天津市', only_polygon=True, wgs84=True)
polygons_hb = get_adm_maps(level='省', province='河北省', only_polygon=True, wgs84=True)
mask_bj = polygons_bj[0].make_mask_array(lon, lat)
mask_tj = polygons_tj[0].make_mask_array(lon, lat)
mask_hb = polygons_hb[0].make_mask_array(lon, lat)
# 合并:网格点在任意一个区域内即保留(False)
merged_mask = np.logical_and(mask_bj, np.logical_and(mask_tj, mask_hb))
ds_masked = ds.where(~merged_mask, np.nan)合并逻辑:
False表示"在区域内"。合并时要求所有掩码都为 True(即所有区域外)时才置为 True。等价于在逻辑与运算后,只要有一个掩码判定为 False(区域内),结果就为 False。
| 参数 | 含义 | 示例 |
|---|---|---|
level | 行政级别:省 / 市 / 区县 | level='省' |
province | 省/直辖市/自治区全称 | '河北省'、'北京市'、'新疆维吾尔自治区' |
city | 地级市全称(市级/县级需要) | '唐山市' |
district | 区县全称(县级需要) | '曹妃甸区' |
only_polygon=True | 仅返回多边形,不包含元数据 | 建议始终设为 True |
wgs84=True | 输出 WGS84 坐标系(经纬度) | 天机数据为经纬度网格,设为 True |
名称规范:行政区域名称必须使用标准全称。例如"新疆维吾尔自治区"而非"新疆"。
make_mask_array 的一维 lon/lat 数组不需要等间距,但必须与 NetCDF 中的坐标一一对应
数据网格应覆盖目标行政区域,否则掩码会将区域外所有点置为 NaN,区域内可能也无有效网格