所谓文无第一,武无第二
气象领域的插值方案是江山辈有才人出,那么我们今天来看看新鲜的插值库xarray-regrid
xarray-regrid 使用 regridding 方法扩展了 xarray,使其能够轻松有效地在两个直线网格之间重新网格化。
其支持以下插值方法
Linear
Nearest-neighbor
Conservative
Cubic
Zonal statistics
“Most common value” (zonal statistics)
“Least common value” (zonal statistics)
公众号:气python风雨
Image Name
关注我获取更多学习资料,第一时间收到我的Python学习资料,也可获取我的联系方式沟通合作
安装非常简单,只需要pip,注意需要python版本大于3.10
!pip install xarray-regrid -i https://pypi.mirrors.ustc.edu.cn/simple/
示例数据使用常见的era5的nc格式
import xarray as xr
ds = xr.open_dataset("/home/mw/input/era5sample8008/era5.nc")
ds
import xarray_regrid
import xarray as xr
from xarray_regrid import Grid
from time import time
# 创建目标网格(45°N-90°N, 90°E-180°E, 0.17°分辨率)
new_grid = Grid(
north=, # 北边界
south=, # 南边界
west=, # 西边界
east=, # 东边界
resolution_lat=0.17, # 纬度分辨率
resolution_lon=0.17 # 经度分辨率
)
target_ds = new_grid.create_regridding_dataset()
# 加载ERA5数据
ds = xr.open_dataset("/home/mw/input/era5sample8008/era5.nc")
# 执行双线性重采样(核心代码)
t_start = time()
regridded_ds = ds.regrid.linear(target_ds) # 线性插值
regridded_ds = regridded_ds.compute() # 触发实际计算
print(f"xarray-regrid耗时: {time()-t_start:.2f}秒")
# 结果验证
print("重采样结果统计:")
print(f"最小值: {regridded_ds['u10'].min().values:.2f}m/s")
print(f"最大值: {regridded_ds['u10'].max().values:.2f}m/s")
xarray-regrid耗时: 5.99秒
重采样结果统计:
最小值: -18.50m/s
最大值: 22.56m/s
ds['u10'][].plot()
<matplotlib.collections.QuadMesh at 0x7fb0fd608b90>
regridded_ds['u10'][].plot()
<matplotlib.collections.QuadMesh at 0x7fb0fd6cf250>
具体操作过程这里
https://www.heywhale.com/mw/project/681ccb6c446db0038d3a6502
cdo更适合写为shell脚本使用,在notebook中不方便
import xarray as xr
import xesmf as xe
from time import time
import numpy as np
# 加载数据
ds = xr.open_dataset("/home/mw/input/era5sample8008/era5.nc")
# 创建目标网格(需手动构建)
target_ds = xr.Dataset({
'lat': (['lat'], np.arange(, , 0.17)), # 纬度坐标
'lon': (['lon'], np.arange(, , 0.17)) # 经度坐标
})
# 步骤1:创建重采样器(耗时最长)
t_start = time()
regridder = xe.Regridder(
ds, # 输入数据集
target_ds, # 目标网格
'bilinear', # 双线性方法
extrap_method='nearest_s2d'# 边界外推方法
)
print(f"xESMF初始化耗时: {time()-t_start:.2f}秒")
# 步骤2:执行重采样
t_start = time()
regridded_ds_emsf = regridder(
ds, # 输入数据
keep_attrs=True# 保留属性
)
print(f"xESMF重采样耗时: {time()-t_start:.2f}秒")
# 结果后处理
regridded_ds_emsf = regridded_ds_emsf.rename({'lat': 'latitude', 'lon': 'longitude'})
# 结果验证
print("重采样结果统计:")
print(f"最小值: {regridded_ds_emsf['u10'].min().values:.2f}m/s")
print(f"最大值: {regridded_ds_emsf['u10'].max().values:.2f}m/s")
xESMF初始化耗时: 13.47秒
xESMF重采样耗时: 5.09秒
重采样结果统计:
最小值: -18.50m/s
最大值: 22.56m/s
regridded_ds_emsf['u10'][].plot()
<matplotlib.collections.QuadMesh at 0x7fb0fd43ca10>
(regridded_ds_emsf['u10'][]-regridded_ds['u10'][]).max()
插值结果一致
功能 | xarray-regrid | CDO | xESMF |
---|---|---|---|
代码量 | 10行 | 需多步脚本 | 15行 |
预处理 | 无需 | 需转64位浮点 | 需手动建网格 |
边界处理 | 自动外推 | 需单独配置 | 需指定参数 |
内存管理 | 支持Dask流式 | 全加载 | 全加载 |
并行能力 | 原生Dask支持 | 需OpenMP编译 | 单线程 |
坐标系支持 | 自动识别 | 需明确定义 | 需明确定义 |
三种方法各有适用场景,但xarray-regrid主打简洁,易上手,且支持dask。对于数据结构简单的大量数据还是挺方便的。
不过在对于多个高度层的数据还没摸索出比较合适的插值方法,容易爆内存
对于结构复杂的nc文件,例如wrf这种不标准的网格,xesmf即可发挥作用 ,其在有权重文件存在下插值速度也是非常快的
而cdo则是在命令行下的快速实现为主,需要操作者对指令与参数比较熟悉
当然最主要的还是我们自身需要了解数据本身的结构才能更好地操作这些工具