3

大気を表す3Dデータがあります。ここで、このデータを共通のZ座標に補間したいと思います(つまり、関数のドクトリングから明らかなはずです)。次のコードは正常に機能しますが、パフォーマンスを向上させる方法があるかどうか疑問に思っていました...

def interpLevel(grid,value,data,interp='linear'):
    """
    Interpolate 3d data to a common z coordinate.

    Can be used to calculate the wind/pv/whatsoever values for a common
    potential temperature / pressure level.

    grid : numpy.ndarray
       The grid. For example the potential temperature values for the whole 3d
       grid.

    value : float
       The common value in the grid, to which the data shall be interpolated.
       For example, 350.0

    data : numpy.ndarray
       The data which shall be interpolated. For example, the PV values for
       the whole 3d grid.

    kind : str
       This indicates which kind of interpolation will be done. It is directly
       passed on to scipy.interpolate.interp1d().

    returs : numpy.ndarray
       A 2d array containing the *data* values at *value*.

    """
    ret = np.zeros_like(data[0,:,:])
    # we need to copy the grid to a new one, because otherwise the flipping
    # done below will be messed up
    gr = np.zeros_like(grid)
    da = np.zeros_like(data)
    for latIdx in xrange(grid.shape[1]):
        for lonIdx in xrange(grid.shape[2]):
            # check if we need to flip the column
            if grid[0,latIdx,lonIdx] > grid[-1,latIdx,lonIdx]:
                gr[:,latIdx,lonIdx] = grid[::-1,latIdx,lonIdx]
                da[:,latIdx,lonIdx] = data[::-1,latIdx,lonIdx]
            else:
                gr[:,latIdx,lonIdx] = grid[:,latIdx,lonIdx]
                da[:,latIdx,lonIdx] = data[:,latIdx,lonIdx]
            f = interpolate.interp1d(gr[:,latIdx,lonIdx], \
                    da[:,latIdx,lonIdx], \
                    kind=interp)
            ret[latIdx,lonIdx] = f(value)
    return ret
4

1 に答える 1

2

まあ、これはそれがより少ないメモリを使用するという理由だけで少しスピードアップを与えるかもしれません。

ret = np.zeros_like(data[0,:,:])
for latIdx in xrange(grid.shape[1]):
    for lonIdx in xrange(grid.shape[2]):
        # check if we need to flip the column
        if grid[0,latIdx,lonIdx] > grid[-1,latIdx,lonIdx]:
            ind = -1
        else:
            ind = 1
        f = interpolate.interp1d(grid[::ind,latIdx,lonIdx], \
                data[::ind,latIdx,lonIdx], \
                kind=interp)
        ret[latIdx,lonIdx] = f(value)
return ret

私がやったことは、grとdaを本当に取り除くことだけです。

それ以外に、この関数を非常に多くの異なる値で呼び出していますか(つまり、値は異なりますが、他のパラメーターは同じです)?その場合、関数が複数の値を処理できるようにすることができます(つまり、値の長さと同じ長さの別の次元をretに追加します)。次に、作成した補間関数をより有効に活用します。

最後の提案は、プロファイラーを試すことです。それはあなたが最も時間を取っているものを見ることができるようになります。

于 2010-02-22T20:37:05.837 に答える