使用 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
将其重新网格到另一个常规网格在内存和时间方面非常浪费。
有几种方法可以对图像进行下采样。至少PIL
和cv2
模块提供下采样功能。如果您想使用 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 方法重新网格化数据时出现意外的内存错误