使用rioxarray转换NetCDF为栅格:空间维度设置报错及变量转维度求助
问题背景
用户尝试用rioxarray将NetCDF文件转为栅格数据,需将文件中作为变量的nav_lon(经度)、nav_lat(纬度)设置为空间维度时触发报错。
原始代码
import xarray as xr import rioxarray as rio nc_file = xr.open_dataset('......') #path to nc data file nc_file = nc_file.set_spatial_dims(x_dim='nav_lon', y_dim='nav_lat') #set spatial dimensions bT = nc_file['votemper'] #extract variable from nc data bT.rio.write_crs("epsg:4326", inplace=True) #define CRS bT.rio.to_raster(r"bottomT_raster.tiff") #save as raster
NetCDF数据集结构
<xarray.Dataset> Dimensions: (y: 86, x: 102, deptht: 1, time_counter: 132) Coordinates: * deptht (deptht) float32 3.047 * time_counter (time_counter) datetime64[ns] 2009-01-16T12:00:00 ... 2019-... Dimensions without coordinates: y, x Data variables: nav_lon (y, x) float32 -26.05 -26.0 -25.95 ... -21.1 -21.05 -21.0 nav_lat (y, x) float32 13.96 13.96 13.96 13.96 ... 18.04 18.04 18.04 votemper (time_counter, y, x) float32 ... vosaline (time_counter, y, x) float32 ...
报错信息
nc_file = nc_file.set_spatial_dims(x_dim='nav_lon', y_dim='nav_lat') Traceback (most recent call last): File "/var/folders/fy/wyzk01_n36jgjq0csnn195080000gn/T/ipykernel_1587/4107632915.py", line 1, in <cell line: 1> nc_file = nc_file.set_spatial_dims(x_dim='nav_lon', y_dim='nav_lat') File "/opt/miniconda3/lib/python3.8/site-packages/xarray/core/common.py", line 239, in __getattr__ raise AttributeError( AttributeError: 'Dataset' object has no attribute 'set_spatial_dims'
问题分析
报错的核心原因:
set_spatial_dims是rioxarray为DataArray专属提供的方法,无法直接在Dataset对象上调用;- 你的NetCDF文件中
nav_lon、nav_lat是二维变量,而非关联到x/y维度的坐标,需要先完成变量到坐标的转换,才能适配栅格转换逻辑。
解决方案
方法一:修正rioxarray处理流程(适配曲线网格)
针对你的曲线网格数据(每个(y,x)点对应独立经纬度),按以下步骤修改代码:
import xarray as xr import rioxarray as rio # 读取NetCDF文件 nc_file = xr.open_dataset('你的文件路径.nc') # 将nav_lon、nav_lat从变量转为数据集坐标 nc_file = nc_file.assign_coords( nav_lon=nc_file.nav_lon, nav_lat=nc_file.nav_lat ) # 提取目标温度变量 bT = nc_file['votemper'] # 为DataArray设置空间维度(使用原有的x、y维度) bT = bT.rio.set_spatial_dims(x_dim='x', y_dim='y') # 写入WGS84坐标系(EPSG:4326) bT.rio.write_crs("epsg:4326", inplace=True) # 保存为TIFF(这里取第一个时间切片,可根据需求调整索引) bT.isel(time_counter=0).rio.to_raster("bottomT_raster.tiff")
方法二:GDAL直接转换(备选方案)
如果rioxarray的曲线网格处理逻辑不符合需求,可直接用GDAL完成转换:
from osgeo import gdal # 打开NetCDF并指定要转换的变量 ds = gdal.Open('NETCDF:"你的文件路径.nc":votemper') # 转换并保存为TIFF格式 gdal.Translate("bottomT_raster.tiff", ds, format="GTiff")
关键补充说明
- 你的数据属于曲线网格(curvilinear grid),每个网格点的经纬度是独立二维数组,而非规则线性维度。处理时空间维度仍为原有的
x/y,nav_lon/nav_lat作为坐标信息记录点位; - 若需将曲线网格转为规则网格,可通过xarray的
interp方法重采样:
# 创建规则经纬度序列 lon_regular = xr.linspace(-26.05, -21.0, 102) lat_regular = xr.linspace(13.96, 18.04, 86) # 重采样到规则网格 bT_regular = bT.interp(x=lon_regular, y=lat_regular)
内容的提问来源于stack exchange,提问作者vinha
相关产品推荐
相关产品推荐

