Xarray处理多维坐标NetCDF数据集:经纬度选值及坐标维度含义咨询
看起来你在处理CORDEX区域模式的非规则网格数据,这种多维坐标的情况确实容易让人困惑,我来一步步解答你的问题:
问题1:能否用sel直接选取指定经纬度和时间的温度值?
直接用ds.temp.sel(time='2018-01-01', lat=-59.71, lon=89.9).values是行不通的,因为你的lat和lon是多维坐标(依赖x和y两个维度),并非Xarray可以直接用sel索引的一维维度坐标。Xarray的sel默认仅支持直接索引“维度坐标”——也就是和数据集维度一一对应的一维坐标,比如你的x、y、time。
那正确的做法是先找到最接近目标经纬度的(x,y)网格点,再用x和y索引。具体代码如下:
import numpy as np # 定义目标参数 target_time = '2018-01-01' target_lat = -59.71 target_lon = 89.9 # 计算每个网格点与目标经纬度的距离平方(省略开根号步骤,提升计算效率) distance_sq = (ds.lat - target_lat)**2 + (ds.lon - target_lon)**2 # 找到距离最小的点的一维索引 min_flat_idx = distance_sq.argmin() # 将一维索引转换为二维的(y,x)索引(对应lat/lon的维度顺序) y_idx, x_idx = np.unravel_index(min_flat_idx, (ds.dims['y'], ds.dims['x'])) # 提取目标温度值 temp_value = ds.temperature.sel(time=target_time, x=x_idx, y=y_idx).values
如果你需要批量处理多个经纬度点,或是想要更精确的插值结果(比如线性插值到目标点),可以结合scipy的插值函数,或是用专门的重格点工具处理。但如果只是获取单个点的值,上面的方法最直接高效。
你之前尝试的ds.tas_ymonmean.sel(time=time, x=lat, y=lon)报错,原因是x和y是整数类型的维度索引,你传入的是浮点数格式的经纬度值,Xarray无法将浮点数映射到整数索引上,因此抛出了类型错误。
问题2:括号里的(y,x)是什么意思?为什么lat和lon都依赖x和y?
括号里的(y,x)表示lat和lon这两个坐标变量是二维变量,它们的取值同时依赖x和y两个维度。这说明你的数据集采用了非规则网格(比如CORDEX EUR-11区域模式常用的旋转极坐标系),而非我们常见的规则经纬度网格(规则网格中lat仅随y变化,lon仅随x变化)。
在这种非规则网格中,每个(x,y)网格点的经纬度都是独立计算的,不存在“x对应经度、y对应纬度”的简单线性关系。比如极地附近的区域,为了提升分辨率会拉伸网格,导致每个网格点的经纬度需要同时通过x和y两个维度来定位。
关于重格点的疑问
重格点(regrid)是将非规则网格数据转换为规则经纬度网格的操作,转换后lat和lon会变成一维的维度坐标,此时你就能直接用sel(lat=..., lon=...)来选值了。但如果只是需要单个或少数几个点的值,重格点会额外增加计算量,不如直接寻找最近网格点的方法高效。
备注:内容来源于stack exchange,提问作者user131627

