2

我正在处理来自 netCDF 文件的气候数据。来自不同模型的数据具有不同的分辨率——因此,有必要将模型“重新网格化”为通用网格分辨率。数据是 3-D(时间、纬度、经度)。为了重新网格化,我在每个时间步将旧网格线性插入到新网格上。

我正在寻找一种方法来提高循环每个时间步的过程效率,因为scipy.interpolate.interp2d一次只能处理两个维度。

有没有什么方法可以有效地在时间序列的两个维度上进行线性重新网格/插值,而无需执行for循环(如下所示)?

import numpy as np
import xarray as xr

#create xarray DataArray to establish resolution we want to regrid to.
ref_lat = np.linspace(-90,89,180)
ref_lon = np.linspace(0,359,360)
ref_grid = xr.DataArray(np.zeros((180,360)),coords=[('lat',ref_lat),('lon',ref_lon)])
x_new = ref_grid.lon
y_new = ref_grid.lat

#original files and dimension
x_old = original_DataArray.lon
y_old = original_DataArray.lat
z_old = original_file #3-D memmap

fout = np.memmap('file_out',dtype='float32',mode='w+',shape=original_file.shape)
#any way to optimize this part??
for t in range(0,original_file.shape[0]):
    f = interpolate.interp2d(x_old,y_old,z_old[t,:,:])
    fout[t,:,:] = f(x_new,y_new)
fout.flush()

*注意:我使用 numpy memmaps 将文件写入磁盘和从磁盘写入文件,因为它们通常太大而无法在内存中处理,而 xarray DataArrays 则用于处理 netCDF 文件。

4

3 回答 3

0

另外,仅供参考,您可以使用ESMpy来加快速度。

于 2019-02-22T23:04:06.710 回答
0

CDAT工具中有一种regrid()方法可以帮助插值到新网格上,而无需手动循环时间片。您可以为函数提供要插入的目标网格:

var1_regrid = var1.regrid(ref_var.getGrid())
var2_regrid = var2.regrid(ref_var.getGrid())
var3_regrid = var3.regrid(ref_var.getGrid())

所以它们可以被放入计算中,比如:

diff = var1_regrid - ref_var
于 2020-08-18T05:20:42.997 回答
0

我认为不可能避免循环,但是由于您的网格在 (lon, lat) 中是常规的,您可以按照文档RectBivariateSpline的建议使用更快的网格。

此外,xarray添加了一个额外的索引层,它不会被您的代码使用,并且可能会不必要地减慢速度。特别是,如果您的数据存储在文件中,则xarray可能仅在被要求时才将其读出。

例如,您可能会这样做:

#original files and dimension
x_old = original_DataArray.lon.values
y_old = original_DataArray.lat.values
z_old = original_file.load().values

并将您的索引循环替换为:

for t, z in enumerate(z_old):
    # z is your 2d array, not sure if this loop is much faster though
于 2016-05-28T13:13:48.030 回答