numpy 数组的最大大小是多少?

Posted

技术标签:

【中文标题】numpy 数组的最大大小是多少?【英文标题】:What's the maximum size of a numpy array? 【发布时间】:2013-01-09 15:01:02 【问题描述】:

我正在尝试创建一个包含 2 708 000 000 个元素的矩阵。当我尝试创建一个这种大小的 numpy 数组时,它给了我一个值错误。有什么办法可以增加最大数组大小?

a=np.arange(2708000000)

ValueError Traceback(最近一次调用最后一次)

ValueError: 超出最大允许大小

【问题讨论】:

大小实际上取决于平台和运行时:mail.scipy.org/pipermail/numpy-discussion/2011-January/… 在我的平台中,限制在 1.15 和 1.16e18 之间。 【参考方案1】:

我能够创建一个大小为 60 亿、占用 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 年已经远超任何可能。有趣的是,“Python Blaze”允许您在磁盘上创建 numpy 数组。我记得前段时间玩过它并创建了一个占用 1TB 磁盘的超大阵列。

【讨论】:

您能提供一个使用 Python Blaze 创建如此大数组的示例吗? @AbdallaEssamAli 我已经很久没有搞砸这个了。在 blaze 文档 (blaze.readthedocs.io/en/latest/index.html) 上有一个对“dask.array” (dask.org) 的引用,它在主页上有一些示例代码。包括导入在内的 2 行代码将为您提供一个示例。【参考方案2】:

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 位才能访问它。另一方面,对于如此大的数据集,您应该考虑使用核外计算的可能性。

【讨论】:

【参考方案3】:

确实和系统最大地址长度有关,简单的说是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 会做得更好:然后你的 ints 或 floats 将只占用 4 或 8 个字节。

从 Python 2.6 开始,您可以使用 sys.getsizeof 函数获取有关对象大小的基本信息。请注意,如果将其应用于列表(或其他容器),则返回的大小不包括包含的列表对象的大小;仅用于容纳这些对象的结构。这是我机器上的一些值。

【讨论】:

没有人在谈论字符串或列表。 Numpy 数组是一个 C 对象,具有 80 字节的固定 Python 开销(在我的机器上)。 可以,不过也是大小限制的问题,arrange是生成一个数组,提问者的问题是超出了元素个数的限制大小。【参考方案4】:

您正在尝试创建一个包含 27 亿个条目的数组。如果您运行 64 位 numpy,每个条目 8 个字节,那么总共将是 20 GB。

所以几乎可以肯定你只是用完了你机器上的内存。 numpy 中没有通用的最大数组大小。

【讨论】:

当然有,就是np.intp数据类型的大小。对于 32 位版本,哪个可能只有 32 位...当然,这对于几乎所有实际目的都与内存不足有关... 这个例子确实是内存问题造成的。但是,我在一个非常大的内存机器上运行我的分析,我不断收到错误...我将创建一个新的问题与实际的工作问题。 如果您尝试创建一个包含 1e30 个元素的数组,它甚至会在尝试分配内存之前引发错误。如果你尝试分配许多较小的数组直到没有剩余空间,那么你会得到一个 MemoryError。 我想指出的是,正如@seberg 所说,最大大小是np.intp,它与您机器上C 的ssize_t 的大小一致。

以上是关于numpy 数组的最大大小是多少?的主要内容,如果未能解决你的问题,请参考以下文章

C 中允许的静态数组的最大大小是多少?

Visual C++ 6.0 中“无符号字符”数组的最大允许大小是多少?

delphi中,数组的最大容量是多少?

我们可以在c ++编程中使用的二维数组的最大大小是多少? [重复]

python数据分析 python numpy--数组--运算,切片和索引

将 numpy 数组复制到 Panda 多索引中(大小相同)