保存WRF vertcross生成的xarray剖面为NetCDF时xy_loc类型报错
错误原因
触发该报错的核心原因是xy_loc坐标存储的是wrf-python自定义的CoordPair类实例,属于NetCDF格式不支持的任意Python对象,xarray无法自动识别其数据类型完成序列化。
从你贴的数据结构看,除了xy_loc外还有两处会导致写入失败的隐患:
- 标量坐标
Time为值是None的object类型,不属于NetCDF支持的标准数据类型 - 属性字段
projection存储的是wrf自定义的LambertConformal投影类实例,同样是不可序列化的Python对象,你之前清理属性时没有处理到这一项。
修复方案
按以下步骤处理后即可正常写入NetCDF:
- 提取
xy_loc中存储的坐标数值,替换原始对象坐标xy_loc里的CoordPair对象本身包含经度、纬度、网格x/y索引的数值属性,直接提取为独立的数值类型坐标即可,不需要保留原始对象:
from wrf import to_np # 提取CoordPair中的数值,转为纯numpy数组 lon_vals = to_np(cross_da.xy_loc.lon) lat_vals = to_np(cross_da.xy_loc.lat) x_idx_vals = to_np(cross_da.xy_loc.x) y_idx_vals = to_np(cross_da.xy_loc.y) # 新增数值坐标,删除原始对象类型的xy_loc cross_da = cross_da.assign_coords( lon = ("cross_line_idx", lon_vals), lat = ("cross_line_idx", lat_vals), grid_xi = ("cross_line_idx", x_idx_vals), grid_yi = ("cross_line_idx", y_idx_vals) ).drop_vars("xy_loc")
- 清理剩余非标准类型的坐标与属性
# 删除值为None的Time标量坐标 cross_da = cross_da.drop_vars("Time") # 将投影对象转为字符串格式存储,不需要的话也可以直接删除该属性 cross_da.attrs["projection"] = str(cross_da.attrs["projection"])
- 执行写入操作
处理完成后直接调用写入接口即可,不会再触发序列化错误:
cross_da.to_netcdf("qvapor_vertcross.nc")
补充说明:提取出的独立经纬度坐标完全可以支撑后续的剖面绘图、数值计算需求,不需要依赖原始的
CoordPair对象;如果后续需要重新用wrf-python处理该数据,直接传入提取好的经纬度、高度坐标即可正常调用相关函数。
内容的提问来源于stack exchange,提问作者Gaelle
相关产品推荐
相关产品推荐

