如何克服 numpy.unique 的 MemoryError

Posted

技术标签:

【中文标题】如何克服 numpy.unique 的 MemoryError【英文标题】:How to overcome MemoryError of numpy.unique 【发布时间】:2017-02-14 03:16:43 【问题描述】:

我使用的是 Numpy 1.11.1 版,必须处理一个二维数组

my_arr.shape = (25000, 25000)

所有值都是整数,我需要一个唯一的数组值列表。当使用lst = np.unique(my_arr) 我得到:

Traceback (most recent call last):
  File "<pyshell#38>", line 1, in <module>
    palette = np.unique(arr)
  File "c:\Python27\lib\site-packages\numpy\lib\arraysetops.py", line 176, in unique
    ar = np.asanyarray(ar).flatten()
MemoryError

我的机器只有 8 GB RAM,但我用另一台 16 GB RAM 的机器试了一下,结果是一样的。监控内存和 CPU 使用情况并不表明问题与 RAM 或 CPU 有关。

原则上,我知道数组包含的值,但是如果输入发生变化怎么办......另外,如果我想用另一个替换数组的值(假设全部 2 为 0),是否需要还有很多内存吗?

【问题讨论】:

Python 32 位还是 64 位? Python 2.7.12 作为 32 位 听起来你的问题就在那里。不要使用 32 位 python。另外,尝试使用尽可能小的 int;也许每个值一个字节就可以了? 嗯,我可以改成 64 位。手头的所有数组仅由 0、1 或 2 组成 - 只是形状很大。 切换到 64 位将允许您在每个进程中使用超过 1gb。使用 my_arr.astype(np.int8) 将使您在内存节省方面获得另一个因素 4。 【参考方案1】:

Python 32 位无法访问超过 4 GiB 的 RAM(通常为 ~2.5 GiB)。显而易见的答案是使用 64 位版本。如果这不起作用,另一种解决方案是使用numpy.memmap 并将数组内存映射到存储在磁盘上的文件中。

【讨论】:

我仍然有一个 64 位的 MemoryError 并使用 numpy.memmap。该数组为floats,形状为(8465, 103114),仅比OP 的数组稍大。 (它来自地理栅格。)

以上是关于如何克服 numpy.unique 的 MemoryError的主要内容,如果未能解决你的问题,请参考以下文章

为啥 pd.unique() 比 np.unique() 快?

Cupy.unique() 函数中是不是有 CuPy 版本支持(轴)选项?任何解决方法?

如何克服 TypeError: unhashable type: 'list'

如何克服 TypeError: unhashable type: 'list'

阅读方法: 如何克服默读

如何克服这个安全问题