我正在尝试创建一个包含2 708 000 000个元素的矩阵。当我尝试创建这个大小的numpy数组时,它给了我一个值错误。有什么办法可以增加最大数组大小吗?
ValueError Traceback(最近一次调用最后一次)
ValueError:超出允许的最大大小
答案 0 :(得分:14)
您正在尝试创建一个包含27亿条目的数组。如果您正在运行64位numpy,每个条目8个字节,则总共为20 GB。
所以几乎可以肯定你机器上的内存不足了。 numpy中没有通用的最大数组大小。
答案 1 :(得分:7)
ValueError表示分配的大小太大,而不是内存不足。在我的笔记本电脑上,使用64位python,如果减少位数,我可以分配它:
In [16]: a=np.arange(2708000000)
---------------------------------------------------------------------------
MemoryError Traceback (most recent call last)
<ipython-input-16-aaa1699e97c5> in <module>()
----> 1 a=np.arange(2708000000)
MemoryError:
# Note I don't get a ValueError
In [17]: a = np.arange(2708000000, dtype=np.int8)
In [18]: a.nbytes
Out[18]: 2708000000
In [19]: a.nbytes * 1e-6
Out[19]: 2708.0
在您的情况下,arange使用int64
位,这意味着它是16倍,或大约43 GB。 32位进程只能访问大约4 GB的内存。
根本原因是用于访问数据的指针大小以及可以用这些位表示的数量:
In [26]: np.iinfo(np.int32)
Out[26]: iinfo(min=-2147483648, max=2147483647, dtype=int32)
In [27]: np.iinfo(np.int64)
Out[27]: iinfo(min=-9223372036854775808, max=9223372036854775807, dtype=int64)
请注意,如果我尝试创建一个荒谬的大数组,我可以复制你的ValueError:
In [29]: a = np.arange(1e350)
---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
<ipython-input-29-230a6916f777> in <module>()
----> 1 a = np.arange(1e350)
ValueError: Maximum allowed size exceeded
如果你的机器有很多内存,正如你所说,它将是64位,所以你应该安装Python 64位才能访问它。另一方面,对于这样的大数据集,您应该考虑使用核心计算的可能性。
答案 2 :(得分:4)
我能够创建一个大小为6Billion的阵列,可以容纳45GB的内存。默认情况下,numpy使用dtype为float64创建数组。通过降低精度,我能够节省大量内存。
np.arange(6000000000,dtype=np.dtype('f8'))
np.arange(6000000000,dtype=np.dtype('f4'))
#etc...
默认== float64
np.float64 - 45.7GB
np.float32 - 22.9GB
np.int8 - 5.7GB
显然,8位整数不能存储值为6B。 我确定在某些时候存在最大尺寸,但我怀疑它在2016年可能已经超过任何可能的事情。有趣的是,&#34; Python Blaze&#34;允许您在磁盘上创建numpy数组。我记得前一段时间玩它并创建一个占用1TB磁盘的超大阵列。
答案 3 :(得分:-4)
确实与系统最大地址长度有关,简单来说就是32位系统或64位系统。以下是对这些问题的解释,最初来自Mark Dickinson
简短回答:Python对象开销正在扼杀你。在64位机器上的Python 2.x中,即使在考虑字符串的内容之前,每个列表条目的字符串列表也会消耗48个字节。对于您描述的阵列大小,这超过了8.7 Gb的开销。在32位机器上,它会好一点:每个列表条目只有28个字节。
更长的解释:你应该知道Python对象本身可能非常大:甚至是简单的对象,如整数,浮点数和字符串。在您的代码中,您最终会得到一系列字符串列表。在我的(64位)机器上,即使是一个空的字符串对象占用40个字节,为此你需要为列表指针添加8个字节,这些指针指向内存中的这个字符串对象。因此,每个条目已经有48个字节,或大约8.7 Gb。鉴于Python一次以8个字节的倍数分配内存,并且你的字符串几乎肯定是非空的,你实际上看的是56或64字节(我不知道你的字符串有多长)每个条目。
可能的解决方案:
(1)您可以根据需要将条目从字符串转换为整数或浮点数,从而做得更好。
(2)通过使用Python的数组类型(与列表不同!)或使用numpy,您可以做得更好:那么你的整数或浮点数每个只需4或8个字节
从Python 2.6开始,您可以使用sys.getsizeof函数获取有关对象大小的基本信息。请注意,如果将其应用于列表(或其他容器),则返回的大小不包含所包含的列表对象的大小;仅用于保存这些对象的结构。这是我机器上的一些值。