如何使用 SciPy 插值 3D 数据时提高性能

发布于 2024-08-22 07:13:52 字数 1818 浏览 8 评论 0原文

我有代表大气的 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

I have 3d-data representing the atmosphere. Now I want to interpolate this data to a common Z coordinate (what I mean by that should be clear from the function's doctring). The following code works fine, but I was wondering if there were a way to improve the performance ...

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

任谁 2024-08-29 07:13:52

好吧,这可能会带来一点点加速,因为它使用的内存更少。

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 添加另一个维度,换句话说,该维度与值的长度一样长)。然后您就可以更好地利用您创建的插值函数。

最后的建议是尝试分析器。它可以让您看到什么花费了最多的时间。

Well, this might give a small speed-up just because it uses less memory.

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

All I've done is get rid of gr and da really.

Other than that, are you calling this function with a whole lot of different values(i.e. value being different but other parameters the same)? If so, you might want to make the function be able to handle multiple values (add another dimension to ret in other words that is as long as the length of values). Then you are making better use of the interpolation function that you've created.

The last suggestion is to try a profiler. It will allow you to see what is taking the most time.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文