使用 scipy interpolate griddata 方法重新网格化数据时出现意外的内存错误

Posted

技术标签:

【中文标题】使用 scipy interpolate griddata 方法重新网格化数据时出现意外的内存错误【英文标题】:Unexpected memory error when regriding data with scipy interpolate griddata method 【发布时间】:2014-08-06 22:55:13 【问题描述】:

我有一个3000x6000 2D 网格(来自 tiff 图像)。我想使用scipy.interpolate 库中的griddata 方法将其重新网格化为较低分辨率的网格。首先,我需要根据我读到的here 形成一个18000000x2 numpy array 作为griddata 的输入。这是我的工作:

import numpy as np
from scipy.interpolate import griddata
x_length = 6000
y_length = 3000
def func(x, y):
    return x*(1-x)*np.cos(4*np.pi*x) * np.sin(4*np.pi*y**2)**2
grid_x, grid_y = np.meshgrid(np.linspace(0,1,x_length),np.linspace(0,1,y_length))
points = np.random.rand(x_length*y_length, 2)
values = func(points[:,0], points[:,1])
grid_z0 = griddata(points, values, (grid_x, grid_y), method='nearest')

我在做griddata 时得到一个MemoryError。我有 8 GB 的 RAM,根据this question 的第一个答案,我不应该收到此错误。

总体而言,将3000x6000 网格重新设置为较低分辨率的网格应该不难,我想我在这里做了一些有趣的事情。我应该让 eMemoryError 使用 8 GB RAM 执行这些代码留置权吗?

P.S:虽然我有一个64-bit 操作系统(Windows 7),但我使用的是以下 Python 版本:

Python 2.7.2 (default, Jun 12 2011, 15:08:59) [MSC v.1500 32 bit (Intel)] on win32

【问题讨论】:

它对我有用。我有 4 GB 的 RAM,并且已经占用了超过 3 个。事实上,在 htop 中我只看到大约 200 MB,而您的每个数组正好是 288 MB。 另外,使用x = np.round(x, 5) 舍入到小数的前 5 位。 @Davidmh 我对问题进行了相当多的编辑。我仍然收到运行代码的MemoryError。你有错误吗? 不,还是不明白。使用量约为 2GB。 这应该为您提供 Python 可访问的所有数组的大小:1e-6 * sum(x.nbytes for x in globals().values() if isinstance(x, np.ndarray))。正如预期的那样,我得到了和以前一样的结果,720 MB。 【参考方案1】:

正如 cmets 指出的那样,您的内存不足。在 64 位 Windows 7 上运行的 32 位 Python 被限制为 2 GB 的内存,而你只是撞到了它。

有三种解决方案:

    获取 64 位 Python。 (建议) 插入几个块(将图像分割成一些合适的重叠部分)(费力) 重新考虑您的插值方法(推荐

如果您有一个常规网格(例如图像),使用griddata 将其重新网格到另一个常规网格在内存和时间方面非常浪费。

有几种方法可以对图像进行下采样。至少PILcv2 模块提供下采样功能。如果您想使用 SciPy 方法,请查看 scipy.ndimage.zoom。它将允许您将图像从一个常规网格重新采样到另一个网格。

【讨论】:

我一定会把我的 Python 改成64-bit。知道我只使用 2 GB 的 RAM 很有用!如果我已经有一个 2D numpy 数组(2D 网格)并且无法再访问 tiff 文件,那么最有效的方法是什么?你认为使用scipy.interpolate 中的RegularGridInterpolator 会是一个不错的选择吗? 如果您有二维数组中的图像数据,那么最简单的方法是使用 scipy.ndimage.zoom(my_img_array, 0.43) 之类的东西将两个方向缩放 0.43(或任何您想要的)。

以上是关于使用 scipy interpolate griddata 方法重新网格化数据时出现意外的内存错误的主要内容,如果未能解决你的问题,请参考以下文章

使用scipy.interpolate.CubicSpline添加或乘以三次样条曲线

如何使 scipy.interpolate 给出超出输入范围的推断结果?

scipy 0.11.0 到 0.12.0 更改了线性 scipy.interpolate.interp1d,破坏了我不断更新的插值器

使用 scipy interpolate griddata 方法重新网格化数据时出现意外的内存错误

差异 scipy interpolate vs mpl griddata

Python scipy.interpolate插值