Python 无法分配形状和数据类型为的数组

Python 无法分配形状和数据类型为的数组,python,numpy,data-science,Python,Numpy,Data Science,在Ubuntu18上,我面临着在numpy中分配巨大数组的问题,而在MacOS上却没有同样的问题 我正在尝试为具有形状(156816,3653806) 与 当我在Ubuntu操作系统上出错时 >>> import numpy as np >>> np.zeros((156816, 36, 53806), dtype='uint8') Traceback (most recent call last): File "<stdin>", line

在Ubuntu18上,我面临着在numpy中分配巨大数组的问题,而在MacOS上却没有同样的问题

我正在尝试为具有形状
(156816,3653806)

当我在Ubuntu操作系统上出错时

>>> import numpy as np
>>> np.zeros((156816, 36, 53806), dtype='uint8')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
numpy.core._exceptions.MemoryError: Unable to allocate array with shape (156816, 36, 53806) and data type uint8
我在某个地方读到,
np.zeros
不应该真正分配数组所需的全部内存,而应该只分配非零元素。尽管Ubuntu机器有64gb内存,而我的MacBookPro只有16gb

版本:

Ubuntu
os -> ubuntu mate 18
python -> 3.6.8
numpy -> 1.17.0

mac
os -> 10.14.6
python -> 3.6.4
numpy -> 1.17.0

PS:在Google Colab上也失败了这可能是由于您的系统模式

在默认模式下,
0

启发式超限制处理。地址空间的明显超限被拒绝。用于典型系统。它确保了严重的野生分配失败,同时允许过度分配以减少交换使用。在此模式下,允许根用户分配稍多的内存。这是默认设置

这里没有很好地解释所使用的确切启发式,但这将在和中进行更多讨论

您可以通过运行

$ cat /proc/sys/vm/overcommit_memory
0
在这种情况下,您正在分配

>>> 156816 * 36 * 53806 / 1024.0**3
282.8939827680588
~282 GB,内核说得很好,显然我不可能将这么多物理页面提交给它,它拒绝分配

如果(以root用户身份)运行:

这将启用“always Overmit”模式,并且您将发现,实际上,系统将允许您进行分配,无论它有多大(至少在64位内存寻址范围内)

我自己在一台有32GB内存的机器上进行了测试。使用Overmit模式
0
我还得到了一个
MemoryError
,但在将其更改回
1
后,它可以工作:

>>> import numpy as np
>>> a = np.zeros((156816, 36, 53806), dtype='uint8')
>>> a.nbytes
303755101056

然后,您可以继续向数组中的任何位置写入数据,并且当您显式地向该页面写入数据时,系统将只分配物理页面。因此,您可以小心地将其用于稀疏阵列。

我在Window上遇到了同样的问题,并找到了此解决方案。因此,如果有人在Windows中遇到这个问题,我的解决方案是增加大小,因为这对我来说也是一个内存过度使用的问题

视窗8

  • 在键盘上按Windows键+X,然后在弹出菜单中单击系统
  • 轻触或单击“高级系统设置”。可能会要求您输入管理员密码或确认您的选择
  • 在“高级”选项卡上的“性能”下,轻按或单击“设置”
  • 点击或单击高级选项卡,然后在虚拟内存下点击或单击更改
  • 清除“自动管理所有驱动器的分页文件大小”复选框
  • 在驱动器[卷标]下,点击或单击包含要更改的分页文件的驱动器
  • 轻按或单击“自定义大小”,在“初始大小(MB)”或“最大大小(MB)”框中输入新大小(以MB为单位),轻按或单击“设置”,然后轻按或单击“确定”
  • 重新启动系统
  • 视窗10

  • 按Windows键
  • 类型系统属性高级
  • 单击以管理员身份运行
  • 在“性能”下,单击“设置”
  • 选择“高级”选项卡
  • 选择更改
  • 取消选中自动管理所有驱动器的分页文件大小
  • 然后选择“自定义大小”并填写适当的大小
  • 按Set,然后按OK,然后退出虚拟内存、性能选项和系统属性对话框
  • 重新启动系统
  • 注意:在本例中,我的系统内存不足,无法容纳~282GB的内存,但在我的特殊情况下,这是可行的

    编辑

    根据建议的页面文件大小建议:

    有一个计算正确页面文件大小的公式。初始大小是系统内存总量的1.5倍。最大尺寸为初始尺寸的三(3)倍。假设您有4GB(1GB=1024MB x 4=4096MB)的内存。初始大小为1.5 x 4096=6144 MB,最大大小为3 x 6144=18432 MB

    要记住以下几点:

    但是,这并没有考虑到其他重要因素和可能是您的计算机所独有的系统设置。同样,让Windows选择使用什么,而不是依赖于在不同计算机上运行的任意公式

    此外:

    增加页面文件大小可能有助于防止Windows中的不稳定和崩溃。但是,硬盘的读/写时间比数据在计算机内存中时慢得多。拥有一个更大的页面文件会给硬盘增加额外的工作,导致其他一切运行变慢。页面文件大小只应在遇到内存不足错误时增加,并且只能作为临时修复。更好的解决办法是给计算机增加更多内存


    我在Windows上也遇到了这个问题。我的解决方案是将Python从32位版本切换到64位版本。事实上,一个32位软件,就像一个32位CPU,可以寻址一个RAM(2^32)。因此,如果您的RAM超过4GB,32位版本就无法利用它

    使用64位版本的Python(在下载页面中标记为x86-64),问题就消失了

    您可以通过输入解释器来检查您的版本。一、 对于64位版本,现在有:
    Python 3.7.5rc1(tags/v3.7.5rc1:4082f600a5,2019年10月1日,20:28:14)[MSC v.1916 64位(AMD64)]
    ,其中[MSC v.1916 64位(AMD64)]表示“64位Python”

    资料来源:


    在我的例子中,添加一个dtype属性将数组的dtype更改为一个较小的类型(从float64到uint8),将数组大小减小到足以在Windows中不抛出MemoryError(64位)


    有时,由于内核已达到极限,会弹出此错误。尝试重新启动内核,重新执行必要的操作
    >>> 156816 * 36 * 53806 / 1024.0**3
    282.8939827680588
    
    $ echo 1 > /proc/sys/vm/overcommit_memory
    
    >>> import numpy as np
    >>> a = np.zeros((156816, 36, 53806), dtype='uint8')
    >>> a.nbytes
    303755101056
    
    mask = np.zeros(edges.shape)
    
    mask = np.zeros(edges.shape,dtype='uint8')
    
    data['label'] = data['label'].astype(np.uint8)