如何在xarray中删除网格点?或获取次邻近有效网格点
解决ERA5数据集查找次邻近非NaN网格点的问题
错误原因分析
你遇到的KeyError本质原因是:
- 你试图删除的
42.36056(纬度)和-71.01056(经度)是气象站的经纬度,并不是ERA5数据集里实际存在的网格点坐标。 - 你的数据集网格是0.1°间隔:纬度从50.0到23.0(步长-0.1),经度从-125.0到-65.0(步长0.1),数据集里不存在
42.36056这种精确值,drop_sel自然找不到对应的轴标签。 - 之前用
sel(..., method='nearest')找到的是数据集里最接近气象站的网格点(比如纬度≈42.4、经度≈-71.0),但该点全为NaN,所以需要定位并跳过它,寻找下一个最近的有效网格点。
可行解决方案
方案1:定位并删除原最近网格点,再找次邻近点
先找到数据集内实际存在的最近网格点坐标,删除后再重新查找次邻近点:
import xarray as xr # 目标气象站经纬度 target_lat = 42.36056 target_lon = -71.01056 # 打开数据集(原始逐小时/日最高温数据均可) NUM_DAYS = 20 df = xr.open_mfdataset( '/glacier1/mmartin/data/ERA5_LandOnly_???????.nc', chunks={'time':24*NUM_DAYS, 'latitude':271, 'longitude':601} ) # 1. 获取数据集内最接近目标的网格点坐标 nearest_lat = df.latitude.sel(latitude=target_lat, method='nearest').item() nearest_lon = df.longitude.sel(longitude=target_lon, method='nearest').item() # 2. 删除该无效网格点 df_filtered = df.drop_sel(latitude=nearest_lat, longitude=nearest_lon) # 3. 查找次邻近的有效网格点 valid_data = df_filtered.sel( latitude=target_lat, longitude=target_lon, method='nearest' )
方案2:直接筛选非NaN的最近网格点(更高效)
无需删除网格点,直接计算所有网格点到目标的距离,筛选出非NaN点中距离最小的,避免重复IO操作:
import xarray as xr import numpy as np # 目标气象站经纬度 target_lat = 42.36056 target_lon = -71.01056 # 打开数据集 NUM_DAYS = 20 df = xr.open_mfdataset( '/glacier1/mmartin/data/ERA5_LandOnly_???????.nc', chunks={'time':24*NUM_DAYS, 'latitude':271, 'longitude':601} ) # 用Haversine公式计算所有网格点到目标的球面距离(单位:km) lat_rad = np.deg2rad(df.latitude) lon_rad = np.deg2rad(df.longitude) target_lat_rad = np.deg2rad(target_lat) target_lon_rad = np.deg2rad(target_lon) dlat = lat_rad - target_lat_rad dlon = lon_rad - target_lon_rad a = np.sin(dlat/2)**2 + np.cos(target_lat_rad) * np.cos(lat_rad) * np.sin(dlon/2)**2 c = 2 * np.arcsin(np.sqrt(a)) distance = 6371 * c # 标记出时间维度上存在有效数据的网格点 valid_mask = ~df.t2m.isnull().all(dim='time') # 给无效点设置极大距离,排序时自动排除 distance_masked = xr.where(valid_mask, distance, np.inf) # 找到距离最小的网格点索引 min_dist_idx = distance_masked.argmin() # 获取该点的有效数据 nearest_valid_data = df.isel( latitude=min_dist_idx.latitude, longitude=min_dist_idx.longitude )
补充说明
- 两种方案均可在计算日最高温前(处理原始逐小时数据)或后执行,逻辑完全一致。
- 若数据集是规则0.1°间隔网格,也可以直接枚举目标点周围的4个邻近网格点(上下左右),检查哪个点有有效数据,这种方法速度更快。
内容的提问来源于stack exchange,提问作者Megan Martin
相关产品推荐
相关产品推荐

