如何将2D数组从较粗的分辨率插值到较细的分辨率

时间:2018-11-20 11:37:00

标签: numpy scipy netcdf python-xarray

假设我有一个形状为(21600,43200)的发射数据, 对应于latlon,即

lat = np.arange(21600)*(-0.008333333)+90
lon = np.arange(43200)*0.00833333-180

我还有一个缩放因子,形状为(720,1440,7),它对应于latlonday of week

lat = np.arange(720)*0.25-90 
lon = np.arange(1440)*0.25-180

现在,我想将因子应用于排放数据,我认为我需要将(720,1440)上的因子内插到(21600,43200)上。之后,我可以将内插因子与排放数据相乘以获得新的排放输出。

但是我在插值方法上有困难。 有人可以给我一些建议吗?

2 个答案:

答案 0 :(得分:3)

这是您尝试执行的插值方式的完整示例。出于示例目的,我使用了形状为emission的{​​{1}}数据和形状为(10, 20)的{​​{1}}数据。它使用scale,这是在常规网格上进行插值的推荐方法:

(5, 10)

输出:

scipy.interpolate.RectBivariateSpline

注释

  • import scipy.interpolate as sci def latlon(res): return (np.arange(res)*(180/res) - 90, np.arange(2*res)*(360/(2*res)) - 180) lat_fine,lon_fine = latlon(10) emission = np.ones(10*20).reshape(10,20) lat_coarse,lon_coarse = latlon(5) scale = np.linspace(0, .5, num=5).reshape(-1, 1) + np.linspace(0, .5, num=10) f = sci.RectBivariateSpline(lat_coarse, lon_coarse, scale) scale_interp = f(lat_em, lon_em) with np.printoptions(precision=1, suppress=True, linewidth=9999): print('original emission data:\n%s\n' % emission) print('original scale data:\n%s\n' % scale) print('interpolated scale data:\n%s\n' % scale_interp) print('scaled emission data:\n%s\n' % (emission*scale_interp)) 中的插值方法期望x和y都严格增加,因此必须确保original emission data: [[1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1.] [1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1.] [1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1.] [1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1.] [1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1.] [1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1.] [1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1.] [1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1.] [1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1.] [1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1.]] original scale data: [[0. 0.1 0.1 0.2 0.2 0.3 0.3 0.4 0.4 0.5] [0.1 0.2 0.2 0.3 0.3 0.4 0.5 0.5 0.6 0.6] [0.2 0.3 0.4 0.4 0.5 0.5 0.6 0.6 0.7 0.8] [0.4 0.4 0.5 0.5 0.6 0.7 0.7 0.8 0.8 0.9] [0.5 0.6 0.6 0.7 0.7 0.8 0.8 0.9 0.9 1. ]] interpolated scale data: [[0. 0. 0.1 0.1 0.1 0.1 0.2 0.2 0.2 0.2 0.3 0.3 0.3 0.4 0.4 0.4 0.4 0.5 0.5 0.5] [0.1 0.1 0.1 0.1 0.2 0.2 0.2 0.3 0.3 0.3 0.3 0.4 0.4 0.4 0.5 0.5 0.5 0.5 0.6 0.6] [0.1 0.2 0.2 0.2 0.2 0.3 0.3 0.3 0.3 0.4 0.4 0.4 0.5 0.5 0.5 0.5 0.6 0.6 0.6 0.6] [0.2 0.2 0.2 0.3 0.3 0.3 0.4 0.4 0.4 0.4 0.5 0.5 0.5 0.5 0.6 0.6 0.6 0.7 0.7 0.7] [0.3 0.3 0.3 0.3 0.4 0.4 0.4 0.4 0.5 0.5 0.5 0.6 0.6 0.6 0.6 0.7 0.7 0.7 0.8 0.8] [0.3 0.3 0.4 0.4 0.4 0.5 0.5 0.5 0.5 0.6 0.6 0.6 0.6 0.7 0.7 0.7 0.8 0.8 0.8 0.8] [0.4 0.4 0.4 0.5 0.5 0.5 0.5 0.6 0.6 0.6 0.7 0.7 0.7 0.7 0.8 0.8 0.8 0.8 0.9 0.9] [0.4 0.5 0.5 0.5 0.5 0.6 0.6 0.6 0.7 0.7 0.7 0.7 0.8 0.8 0.8 0.9 0.9 0.9 0.9 0.9] [0.5 0.5 0.6 0.6 0.6 0.6 0.7 0.7 0.7 0.7 0.8 0.8 0.8 0.9 0.9 0.9 0.9 1. 1. 1. ] [0.5 0.5 0.6 0.6 0.6 0.6 0.7 0.7 0.7 0.7 0.8 0.8 0.8 0.9 0.9 0.9 0.9 1. 1. 1. ]] scaled emission data: [[0. 0. 0.1 0.1 0.1 0.1 0.2 0.2 0.2 0.2 0.3 0.3 0.3 0.4 0.4 0.4 0.4 0.5 0.5 0.5] [0.1 0.1 0.1 0.1 0.2 0.2 0.2 0.3 0.3 0.3 0.3 0.4 0.4 0.4 0.5 0.5 0.5 0.5 0.6 0.6] [0.1 0.2 0.2 0.2 0.2 0.3 0.3 0.3 0.3 0.4 0.4 0.4 0.5 0.5 0.5 0.5 0.6 0.6 0.6 0.6] [0.2 0.2 0.2 0.3 0.3 0.3 0.4 0.4 0.4 0.4 0.5 0.5 0.5 0.5 0.6 0.6 0.6 0.7 0.7 0.7] [0.3 0.3 0.3 0.3 0.4 0.4 0.4 0.4 0.5 0.5 0.5 0.6 0.6 0.6 0.6 0.7 0.7 0.7 0.8 0.8] [0.3 0.3 0.4 0.4 0.4 0.5 0.5 0.5 0.5 0.6 0.6 0.6 0.6 0.7 0.7 0.7 0.8 0.8 0.8 0.8] [0.4 0.4 0.4 0.5 0.5 0.5 0.5 0.6 0.6 0.6 0.7 0.7 0.7 0.7 0.8 0.8 0.8 0.8 0.9 0.9] [0.4 0.5 0.5 0.5 0.5 0.6 0.6 0.6 0.7 0.7 0.7 0.7 0.8 0.8 0.8 0.9 0.9 0.9 0.9 0.9] [0.5 0.5 0.6 0.6 0.6 0.6 0.7 0.7 0.7 0.7 0.8 0.8 0.8 0.9 0.9 0.9 0.9 1. 1. 1. ] [0.5 0.5 0.6 0.6 0.6 0.6 0.7 0.7 0.7 0.7 0.8 0.8 0.8 0.9 0.9 0.9 0.9 1. 1. 1. ]] 数据排列在网格中,使得:< / p>

    scipy.interpolate

    而不是:

    emission

    就像上面一样。您可以像这样翻转lat = np.arange(21600)*0.008333333 - 90 数据:

    lat = np.arange(21600)*(-0.008333333) + 90
    

答案 1 :(得分:1)

如果您只是在寻找最近的邻居或线性插值,则可以使用xarray的本机da.interp方法:

scaling_interped = scaling_factor.interp(
    lon=emissions.lon,
    lat=emissions.lat,
    method='nearest')  # or 'linear'

请注意,这将大大增加数组的大小。假设这些是64位浮点数,结果将大约为(21600*43200*7)*8/(1024**3)48.7 GB。通过按星期几对数组进行分块并进行计算out of core with dask,可以将内存大小减少7倍。

如果要使用除最接近或线性以外的插值方案,请使用方法suggested by tel