用SciPy进行规则网格空间插值

气象上,分析不同空间分辨率的网格数据时,常需要将它们统一插值到一种网格上。本文介绍用Python的科学分析库SciPy完成这一任务。

数据1:CERES的气溶胶光学厚度数据(time x lat x lon),空间分辨率1 x 1度。

数据2:ERA5气象场数据,空间分辨率0.25 x 0.25度。

目标:将CERES气溶胶光学厚度插值到ERA5的0.25 x 0.25度网格上。

动手干吧:

首先,调入所需的函数库,读入源数据(CERES光学厚度)及其经纬度坐标信息。

from scipy import interpolate
import numpy as np
import matplotlib.pyplot as plt
import netCDF4 as nc

CERES_name = "./CERES_SYN1deg-Month_Terra-Aqua-MODIS_Ed4.1_Subset_200003-202308.nc"
ERA5_name = "./ERA5_surface_hrly_20190701.nc"
F_CERES_in = nc.Dataset(CERES_name, "r")
F_ERA5_in = nc.Dataset(ERA5_name,"r")

AOD_550 = np.array(F_CERES_in.variables["ini_aod55_mon"][0,:,:])
lat_CERES = np.array(F_CERES_in.variables["lat"])
lon_CERES = np.array(F_CERES_in.variables["lon"])

接下来,让我们从ERA5数据获取目标网格的信息:

lat_ERA5 = np.array(F_ERA5_in.variables["latitude"])
lon_ERA5 = np.array(F_ERA5_in.variables["longitude"])

到了最关键的步骤了——进行插值。我们使用的是SciPy的interpolate子库的RegularGridInterpolator函数。这一函数是专门用来进行规则网格插值的,支持线性(linear)、临近(nearist)、三次样条插值(cubic)等。

这一插值要分两部走。第一步:根据源数据空间曲面建立插值函数;第二步:利用该函数和新网格信息,获取新网格上的值(这里需要先将1维经纬度转为与新网格对应的经度、纬度二维矩阵)。注意,np.meshgrid的indexing有两个选项:‘ij’和‘xy’,代表两种不同数据排列顺序,例如 lat x lon 大小是11 x 22,则indexing=‘ij’的结果是 11x22 大小的矩阵,而 indexing = ‘xy’的结果是 22x11大小的矩阵。

# Step 1:
interp = interpolate.RegularGridInterpolator((lat_CERES, lon_CERES), AOD_550, method='linear')

# Step 2: 
lat_ERA5_g, lon_ERA5_g  = np.meshgrid(lat_ERA5, lon_ERA5)
AOD_550_new = interp((LAT_ERA5_g, lon_ERA5_g))

至此,插值完成,AOD_550_new即为插值出来的新网格上的数据。

接着进行可视化,代码和插值前后的图如下:

(细心的朋友也许会发现,两组数据的纬度排列顺序是不一样的,CERES从南向北,而ERA5从北向南。但是这不影响插值过程,只是在可视化时需至北向南排列)

(细心的朋友还会发现,插值前后数据的区域范围不同,本例子用全球数据插值到中国区域,多出的数据并不影响插值效果。)

fig, ax = plt.subplots(2,1,layout='constrained')

extent = (min(lon_CERES), max(lon_CERES), min(lat_CERES), max(lat_CERES))
plot1 = ax[0].imshow(AOD_550[::-1,:],cmap='RdBu_r', vmin=0, vmax=1.2, extent=extent)
ax[0].set_xlabel('longitude')
ax[0].set_ylabel('latitude')
ax[0].set_title('AOD550 (Before Interpolation)')
fig.colorbar(plot1, shrink=0.7)

extent = (min(lon_ERA5), max(lon_ERA5), min(lat_ERA5), max(lat_ERA5))
plot2 = ax[1].imshow(AOD_550_new,cmap='RdBu_r', vmin=0, vmax=1.2, extent=extent)
ax[1].set_xlabel('longitude')
ax[1].set_ylabel('latitude')
ax[1].set_title("AOD550 (After Interpolation)")
fig.colorbar(plot2, shrink=0.7)
plt.show()

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值