NumPy:3D阵列的1D插值

时间:2012-12-17 23:32:07

标签: python multidimensional-array numpy interpolation

我对NumPy很新。任何人都有想法制作这个代码,特别是嵌套循环,更紧凑/高效? BTW,dist和data是三维numpy数组。

def interpolate_to_distance(self,distance):

    interpolated_data=np.ndarray(self.dist.shape[1:])
    for j in range(interpolated_data.shape[1]):
        for i in range(interpolated_data.shape[0]):
            interpolated_data[i,j]=np.interp(
                                  distance,self.dist[:,i,j],self.data[:,i,j])

    return(interpolated_data)

谢谢!

1 个答案:

答案 0 :(得分:2)

好吧,我会对此嗤之以鼻:

def interpolate_to_distance(self, distance):
    dshape = self.dist.shape
    dist = self.dist.T.reshape(-1, dshape[-1])
    data = self.data.T.reshape(-1, dshape[-1])
    intdata = np.array([np.interp(distance, di, da)
                        for di, da in zip(dist, data)])
    return intdata.reshape(dshape[0:2]).T

它至少删除了一个循环(以及那些嵌套索引),但它并不比原始循环快得多,根据IPython中%timeit的速度快〜20%。另一方面,有很多(可能是不必要的,最终)转置和重塑正在进行中。

为了记录,我将它包装在一个虚拟类中,并用随机数填充一些3 x 3 x 3阵列进行测试:

import numpy as np

class TestClass(object):
    def interpolate_to_distance(self, distance):
        dshape = self.dist.shape
        dist = self.dist.T.reshape(-1, dshape[-1])
        data = self.data.T.reshape(-1, dshape[-1])
        intdata = np.array([np.interp(distance, di, da)
                            for di, da in zip(dist, data)])
        return intdata.reshape(dshape[0:2]).T

    def interpolate_to_distance_old(self, distance):
        interpolated_data=np.ndarray(self.dist.shape[1:])
        for j in range(interpolated_data.shape[1]):
            for i in range(interpolated_data.shape[0]):
                interpolated_data[i,j]=np.interp(
                           distance,self.dist[:,i,j],self.data[:,i,j])
        return(interpolated_data)

if __name__ == '__main__':
    testobj = TestClass()

    testobj.dist = np.random.randn(3, 3, 3)
    testobj.data = np.random.randn(3, 3, 3)

    distance = 0
    print 'Old:\n', testobj.interpolate_to_distance_old(distance)
    print 'New:\n', testobj.interpolate_to_distance(distance)

哪些打印件(针对我特定的一组randoms):

Old:
[[-0.59557042 -0.42706077  0.94629049]
 [ 0.55509032 -0.67808257 -0.74214045]
 [ 1.03779189 -1.17605275  0.00317679]]
New:
[[-0.59557042 -0.42706077  0.94629049]
 [ 0.55509032 -0.67808257 -0.74214045]
 [ 1.03779189 -1.17605275  0.00317679]]

我也试过np.vectorize(np.interp)但是无法让它发挥作用。我怀疑如果它确实有效会更快。

我无法使np.fromfunction工作,因为它将(2)3 x 3(在本例中)索引数组传递给np.interp,从{{1}获得相同的数组}}。

另一个注意事项:根据np.mgrid的文档,

  

np.interp未检查x坐标序列np.interp是否正在增加。如果   xp没有增加,结果是无稽之谈。一个简单的检查   增长是::

xp

显然,我的随机数违反了“不断增加”的规则,但你必须要小心。