2011-10-13 68 views
2

我有一个数组,我想插入第一个轴。目前,我正在做这样的例子:在Python中插值3d数组。如何避免循环?

import numpy as np 
from scipy.interpolate import interp1d 

array = np.random.randint(0, 9, size=(100, 100, 100)) 
new_array = np.zeros((1000, 100, 100)) 
x = np.arange(0, 100, 1) 
x_new = np.arange(0, 100, 0.1) 

for i in x: 
    for j in x: 
     f = interp1d(x, array[:, i, j]) 
     new_array[:, i, j] = f(xnew) 

我使用的数据代表一个域中的每个纬度和经度10年5天的平均值的。我想创建一个日常值的数组。

我也试过使用样条线。我真的不知道他们是如何工作的,但速度并不快。

有没有办法做到这一点,而不使用for循环? 如果必须使用for循环,还有其他方法可以加速吗?

非常感谢您的任何建议。

回答

6

您可以指定一个轴参数interp1d:

 
import numpy as np 
from scipy.interpolate import interp1d 
array = np.random.randint(0, 9, size=(100, 100, 100)) 
x = np.linspace(0, 100, 100) 
x_new = np.linspace(0, 100, 1000) 
new_array = interp1d(x, array, axis=0)(x_new) 
new_array.shape # -> (1000, 100, 100) 

+0

好点!如果OP想要真正的一维插值(而不是双线性),那么这就是要走的路。 –

+0

这也很好。谢谢!有趣的是(至少在这种情况下)这种方法导致内插数组的平均值更接近原始数组的平均值。 – nicholaschris

5

由于您正在插入有规律的网格数据,请查看使用scipy.ndimage.map_coordinates

作为一个简单的例子:

import numpy as np 
import scipy.ndimage as ndimage 

interp_factor = 10 
nx, ny, nz = 100, 100, 100 
array = np.random.randint(0, 9, size=(nx, ny, nz)) 

# If you're not familiar with mgrid: 
# http://docs.scipy.org/doc/numpy/reference/generated/numpy.mgrid.html 
new_indicies = np.mgrid[0:nx:interp_factor*nx*1j, 0:ny, 0:nz] 

# order=1 indicates bilinear interpolation. Default is 3 (cubic interpolation) 
# We're also indicating the output array's dtype should be the same as the 
# original array's. Otherwise, a new float array would be created. 
interp_array = ndimage.map_coordinates(array, new_indicies, 
             order=1, output=array.dtype) 
interp_array = interp_array.reshape((interp_factor * nx, ny, nz)) 
+0

十分感谢,它看起来像它会工作。它会与掩码数组一起工作吗? – nicholaschris

+0

编辑:非常感谢,它看起来像它的效果很好。我正在使用它作为要插入的数组的掩码数组。这会使事情复杂化吗?如果我设置output = array.dtype有一个奇怪的结果,但如果我离开输出为默认它似乎工作正常。 – nicholaschris