2

私はNumPyにかなり慣れていません。このコード、特にネストされたループをよりコンパクト/効率的にするためのアイデアはありますか? ところで、dist と data は 3 次元の 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)

ありがとう!

4

1 に答える 1

3

さて、私はこれで盗品を取ります:

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

少なくとも 1 つのループ (およびそれらのネストされたインデックス) を削除しますが、元のループよりもそれほど高速ではなく%timeit、IPython によると最大 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)

どちらが出力されますか(私の特定のランダムセットの場合):

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.interpnp.mgrid

もう1つの注意:のドキュメントによるとnp.interp

np.interpxpx 座標シーケンスが増加していることをチェックしません。が増加しない場合 xp、結果はナンセンスです。増加の簡単なチェックは次のとおりです::

np.all(np.diff(xp) > 0)

明らかに、私の乱数は「常に増加する」ルールに違反していますが、もっと注意する必要があります。

于 2012-12-18T04:37:39.763 に答える