当处理气象数据时,经常会遇到不同分辨率的数据集需要一起使用的情况。
小编在气象家园看到如下帖子:
下了两份ERA5资料,一份的分辨率是0.250.25,另一份地面气压分辨率是0.10.1,不同分辨率没办法一起计算,求助怎样转分辨率并输出文件?
本文将介绍两种方法来统一ERA5数据的分辨率:使用CDO命令行工具和Python的xesmf库。
1. 创建样例数据
因为手头没有现成的数据,直接制造文件是比较快捷的
首先,我们使用xarray创建两个不同分辨率的样例数据集并保存为NetCDF文件。
import xarray as xr
import numpy as np
# 创建0.25°分辨率的样例数据
lat_025 = np.arange(-90, 90.25, 0.25)
lon_025 = np.arange(0, 360, 0.25)
data_025 = np.random.rand(len(lat_025), len(lon_025))
ds_025 = xr.Dataset(
{"temperature": (["latitude", "longitude"], data_025)},
coords={
"latitude": lat_025,
"longitude": lon_025,
},
)
ds_025.to_netcdf("era5_025deg.nc")
# 创建0.1°分辨率的样例数据
lat_01 = np.arange(-90, 90.1, 0.1)
lon_01 = np.arange(0, 360, 0.1)
data_01 = np.random.rand(len(lat_01), len(lon_01))
ds_01 = xr.Dataset(
{"surface_pressure": (["latitude", "longitude"], data_01)},
coords={
"latitude": lat_01,
"longitude": lon_01,
},
)
ds_01.to_netcdf("era5_01deg.nc")
!ncdump -c /home/mw/project/era5_01deg.nc | head -20
netcdf era5_01deg {
dimensions:
latitude = 1801 ;
longitude = 3600 ;
variables:
double surface_pressure(latitude, longitude) ;
surface_pressure:_FillValue = NaN ;
double latitude(latitude) ;
latitude:_FillValue = NaN ;
double longitude(longitude) ;
longitude:_FillValue = NaN ;
data:
latitude = -90, -89.9, -89.8, -89.7, -89.6, -89.5, -89.4, -89.3, -89.2,
-89.1000000000001, -89.0000000000001, -88.9000000000001,
-88.8000000000001, -88.7000000000001, -88.6000000000001,
-88.5000000000001, -88.4000000000001, -88.3000000000001,
-88.2000000000001, -88.1000000000001, -88.0000000000001,
-87.9000000000001, -87.8000000000001, -87.7000000000001,
-87.6000000000001, -87.5000000000001, -87.4000000000001,
!ncdump -c /home/mw/project/era5_025deg.nc | head -20
netcdf era5_025deg {
dimensions:
latitude = 721 ;
longitude = 1440 ;
variables:
double temperature(latitude, longitude) ;
temperature:_FillValue = NaN ;
double latitude(latitude) ;
latitude:_FillValue = NaN ;
double longitude(longitude) ;
longitude:_FillValue = NaN ;
data:
latitude = -90, -89.75, -89.5, -89.25, -89, -88.75, -88.5, -88.25, -88,
-87.75, -87.5, -87.25, -87, -86.75, -86.5, -86.25, -86, -85.75, -85.5,
-85.25, -85, -84.75, -84.5, -84.25, -84, -83.75, -83.5, -83.25, -83,
-82.75, -82.5, -82.25, -82, -81.75, -81.5, -81.25, -81, -80.75, -80.5,
-80.25, -80, -79.75, -79.5, -79.25, -79, -78.75, -78.5, -78.25, -78,
-77.75, -77.5, -77.25, -77, -76.75, -76.5, -76.25, -76, -75.75, -75.5,
-75.25, -75, -74.75, -74.5, -74.25, -74, -73.75, -73.5, -73.25, -73,
当然使用cdo查看网格会更简洁(大概)
!cdo griddes /home/mw/project/era5_01deg.nc
#
# gridID 1
#
gridtype = generic
gridsize = 6483600
xsize = 3600
ysize = 1801
xname = longitude
yname = latitude
xfirst = 0
xinc = 0.1
yfirst = -90
yinc = 0.0999999999999943
[32mcdo griddes: [0mProcessed 1 variable [0.08s 51MB]
!cdo griddes /home/mw/project/era5_025deg.nc
#
# gridID 1
#
gridtype = generic
gridsize = 1038240
xsize = 1440
ysize = 721
xname = longitude
yname = latitude
xfirst = 0
xinc = 0.25
yfirst = -90
yinc = 0.25
[32mcdo griddes: [0mProcessed 1 variable [0.05s 51MB]
CDO (Climate Data Operators) 是我们的老朋友了,专门用于处理气候和NWP模型数据。对于nc数据可谓是瑞士军刀一般的存在
首先,我们需要获取目标网格的描述文件:
!cdo griddes era5_025deg.nc > grid_025.txt
!cdo griddes era5_01deg.nc > grid_01.txt
这会生成一个描述0.25°网格的文本文件。
!cat /home/mw/project/grid_025.txt
#
# gridID 1
#
gridtype = generic
gridsize = 1038240
xsize = 1440
ysize = 721
xname = longitude
yname = latitude
xfirst = 0
xinc = 0.25
yfirst = -90
yinc = 0.25
将0.1°分辨率的数据插值到0.25°分辨率:
!cdo remapbil,grid_025.txt era5_01deg.nc era5_01deg_regridded_to_025.nc
[31m
cdo remapbil (Abort): [0mUnsupported target grid type (generic)!
坏了,cdo不支持这个 grid type (generic)
那么只能手动修改了
!sed -i "s/generic/lonlat/g" /home/mw/project/grid_025.txt
!cat /home/mw/project/grid_025.txt
#
# gridID 1
#
gridtype = lonlat
gridsize = 1038240
xsize = 1440
ysize = 721
xname = longitude
yname = latitude
xfirst = 0
xinc = 0.25
yfirst = -90
yinc = 0.25
!sed -i "s/generic/lonlat/g" /home/mw/project/grid_01.txt
!cat /home/mw/project/grid_01.txt
#
# gridID 1
#
gridtype = lonlat
gridsize = 6483600
xsize = 3600
ysize = 1801
xname = longitude
yname = latitude
xfirst = 0
xinc = 0.1
yfirst = -90
yinc = 0.0999999999999943
!cdo setgrid,grid_025.txt era5_025deg.nc era5_025deg_002.nc
!cdo griddes /home/mw/project/era5_025deg_002.nc
[32mcdo setgrid: [0mProcessed 1038240 values from 1 variable over 1 timestep [0.13s 5096MB]
#
# gridID 1
#
gridtype = lonlat
gridsize = 1038240
xsize = 1440
ysize = 721
xname = longitude
xlongname = "longitude"
xunits = "degrees_east"
yname = latitude
ylongname = "latitude"
yunits = "degrees_north"
xfirst = 0
xinc = 0.25
yfirst = -90
yinc = 0.25
[32mcdo griddes: [0mProcessed 1 variable [0.03s 5096MB]
!cdo setgrid,grid_01.txt era5_01deg.nc era5_01deg_002.nc
!cdo griddes /home/mw/project/era5_01deg_002.nc
[32mcdo setgrid: [0mProcessed 6483600 values from 1 variable over 1 timestep [0.37s 5096MB]
#
# gridID 1
#
gridtype = lonlat
gridsize = 6483600
xsize = 3600
ysize = 1801
xname = longitude
xlongname = "longitude"
xunits = "degrees_east"
yname = latitude
ylongname = "latitude"
yunits = "degrees_north"
xfirst = 0
xinc = 0.1
yfirst = -90
yinc = 0.0999999999999943
[32mcdo griddes: [0mProcessed 1 variable [0.04s 5096MB]
!cdo remapbil,grid_025.txt era5_01deg_002.nc era5_01deg_regridded_to_025.nc
[32mcdo remapbil: [0mBilinear weights from lonlat (3600x1801) to lonlat (1440x721) grid
cdo remapbil: 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 3 3 3 3 3 3 3 3 3 3 4 4 4 4 4 4 4 4 4 4 5 5 5 5 5 5 5 5 5 5 6 6 6 6 6 6 6 6 6 6 7 7 7 7 7 7 7 7 7 7 8 8 8 8 8 8 8 8 8 8 9 9 9 9 9 9 9 9 9 91[32mcdo remapbil: [0mProcessed 6483600 values from 1 variable over 1 timestep [0.92s 5096MB]
这个命令使用双线性插值法(remapbil)将输入文件(era5_01deg.nc)插值到grid_025.txt描述的网格上,并输出新文件。
文件生成并不符合cdo的格式,需要使用set指令调整一下。
插值速度是非常快的,按照官方说法可以达到c语言的程度,可以看到不到一秒就完成了
xesmf是一个基于ESMF的Python库,专门用于地球科学数据的重网格化。
pip install xesmf
import xarray as xr
import xesmf as xe
# 加载数据
ds_target = xr.open_dataset("era5_025deg.nc") # 目标网格
ds_source = xr.open_dataset("era5_01deg.nc") # 源数据
# 创建重网格器
regridder = xe.Regridder(ds_source, ds_target, "bilinear")
# 执行重网格化
ds_regridded = regridder(ds_source)
# 保存结果
ds_regridded.to_netcdf("era5_01deg_regridded_to_025_xesmf.nc")
!cdo griddes /home/mw/project/era5_01deg_regridded_to_025_xesmf.nc
#
# gridID 1
#
gridtype = generic
gridsize = 1038240
xsize = 1440
ysize = 721
xname = longitude
yname = latitude
xfirst = 0
xinc = 0.25
yfirst = -90
yinc = 0.25
[32mcdo griddes: [0mProcessed 1 variable [0.04s 5096MB]
如果格式较为特殊,建议使用python更加便捷,虽然牺牲了处理速度
通过以上方法,你可以轻松地将不同分辨率的ERA5数据统一到相同网格上,便于后续的分析和计算。
参考
https://cloud.tencent.com/developer/ask/sof/1272125
扫码关注腾讯云开发者
领取腾讯云代金券
Copyright © 2013 - 2025 Tencent Cloud. All Rights Reserved. 腾讯云 版权所有
深圳市腾讯计算机系统有限公司 ICP备案/许可证号:粤B2-20090059 深公网安备号 44030502008569
腾讯云计算(北京)有限责任公司 京ICP证150476号 | 京ICP备11018762号 | 京公网安备号11010802020287
Copyright © 2013 - 2025 Tencent Cloud.
All Rights Reserved. 腾讯云 版权所有