Numpy 如何将2D阵列从较粗的分辨率插值到较细的分辨率

Numpy 如何将2D阵列从较粗的分辨率插值到较细的分辨率,numpy,scipy,netcdf,python-xarray,Numpy,Scipy,Netcdf,Python Xarray,假设我有一个具有形状(2160043200)的发射数据, 对应于lat和lon,即 lat = np.arange(21600)*(-0.008333333)+90 lon = np.arange(43200)*0.00833333-180 我还有一个比例因子,形状为(7201440,7),对应于lat、lon、一周中的几天,以及 lat = np.arange(720)*0.25-90 lon = np.arange(1440)*0.25-180 现在,我想将系数应用于排放数据,我想我需

假设我有一个具有形状
(2160043200)
的发射数据, 对应于
lat
lon
,即

lat = np.arange(21600)*(-0.008333333)+90
lon = np.arange(43200)*0.00833333-180
我还有一个比例因子,形状为
(7201440,7)
,对应于
lat
lon
一周中的几天
,以及

lat = np.arange(720)*0.25-90 
lon = np.arange(1440)*0.25-180
现在,我想将系数应用于排放数据,我想我需要将
(7201440)
上的系数插值到
(2160043200)
。之后,我可以将插值因子与排放数据相乘,以获得新的排放输出

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

这里有一个完整的例子,说明您正在尝试进行的插值。例如,我使用了带有形状的
排放数据
和带有形状的
数据
(10,20)
,以及带有形状的
数据
(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))
哪些产出:

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. ]]
笔记
  • scipy.interpolate
    中的插值方法预计x和y都会严格增加,因此您必须确保
    发射
    数据以网格形式排列,以便:

    lat = np.arange(21600)*0.008333333 - 90
    
    而不是:

    lat = np.arange(21600)*(-0.008333333) + 90
    
    就像你上面说的。您可以像这样翻转
    排放
    数据:

    emission = emission[::-1, :]
    

    • 下面是一个完整的插值示例。例如,我使用了带有形状的
      排放数据
      和带有形状的
      数据
      (10,20)
      ,以及带有形状的
      数据
      (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))
      
      哪些产出:

      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. ]]
      
      笔记
      • scipy.interpolate
        中的插值方法预计x和y都会严格增加,因此您必须确保
        发射
        数据以网格形式排列,以便:

        lat = np.arange(21600)*0.008333333 - 90
        
        而不是:

        lat = np.arange(21600)*(-0.008333333) + 90
        
        就像你上面说的。您可以像这样翻转
        排放
        数据:

        emission = emission[::-1, :]
        

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

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


      如果要使用除“最近邻”或“线性”以外的插值方案,请使用该方法。

      如果只是查找“最近邻”或“线性”插值,则可以使用xarray的本机方法:

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

      如果要使用除“最近”或“线性”以外的插值方案,请使用该方法。

      应该可以解决您的问题。。。只要你能把所有的东西都放在内存中(如果你不能,你可以逐段计算插值)。应该解决你的问题。。。只要你能把所有的东西都放在内存中(如果你不能,你可以逐段计算插值)。