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倍
如果要使用除“最近”或“线性”以外的插值方案,请使用该方法。应该可以解决您的问题。。。只要你能把所有的东西都放在内存中(如果你不能,你可以逐段计算插值)。应该解决你的问题。。。只要你能把所有的东西都放在内存中(如果你不能,你可以逐段计算插值)。