Как повысить производительность при интерполяции трехмерных данных с помощью SciPy - PullRequest
3 голосов
/ 22 февраля 2010

У меня есть 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

1 Ответ

2 голосов
/ 22 февраля 2010

Ну, это может дать небольшое ускорение только потому, что он использует меньше памяти.

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

Все, что я сделал, это действительно избавился от гр и да.

Кроме этого, вы вызываете эту функцию с множеством разных значений (т. Е. Значения разные, но другие параметры одинаковые)? Если это так, вы можете захотеть сделать так, чтобы функция могла обрабатывать несколько значений (добавьте другое измерение, чтобы повторять это другими словами, длина которых равна длине значений). Тогда вы лучше используете созданную вами функцию интерполяции.

Последнее предложение - попробовать профилировщик . Это позволит вам увидеть, что занимает больше всего времени.

...