python - 在Python中生成非常大的二维数组?

标签 python arrays matrix byte ram

我想使用列表列表生成非常大的二维数组(或者,换句话说,矩阵)。每个元素都应该是一个 float 。

因此,仅举一个例子,我们假设有以下代码:

import numpy as np

N = 32000

def largeMat():
    m = []
    for i in range(N):
        l = list(np.ones(N))
        m.append(l)
        if i % 1000 == 0:
            print i
    return m

m = largeMat()

我有 12GB RAM,但是当代码到达矩阵的第 10000 行时,我的 RAM 已经满了。现在,如果我没记错的话,每个 float 都是 64 位大(或 8 字节),所以总占用的 RAM 应该是:

32000 * 32000 * 8 / 1 MB = 8192 MB

为什么 python 会填满我的整个 RAM,甚至开始分配到交换区?

最佳答案

Python 不一定以最紧凑的形式存储列表项,因为列表需要指向下一项的指针等。这是拥有允许删除、插入等的数据类型的副作用。对于简单的两个 -链接列表的用法是两个指针加上值,在 64 位机器中,列表中的每个浮点项有 24 个八位字节。在实践中,实现并没有那么愚蠢,但仍然存在一些开销。

如果您想要简洁的格式,我建议使用 numpy.array 因为它会占用您认为需要的字节数(加上一点点开销)。

编辑哎呀。不必要。解释错误,建议有效。 numpy 是正确的工具,因为 numpy.array 正是出于这个原因而存在。然而,问题很可能是其他的。即使需要很长时间(大约 2 分钟),我的计算机也会运行该过程。另外,在此之后退出 python 需要很长时间(实际上,它挂起了)。 python 进程的内存使用量(如 top 报告)峰值为 10 000 MB,然后下降到略低于 9 000 MB。分配的 numpy 数组可能不会很快被垃圾收集。

但是关于我的机器中的原始数据大小:

>>> import sys
>>> l = [0.0] * 1000000
>>> sys.getsizeof(l)
8000072

因此,每个列表似乎有 72 个八位字节的固定开销。

>>> listoflists = [ [1.0*i] * 1000000 for i in range(1000)]
>>> sys.getsizeof(listoflists)
9032
>>> sum([sys.getsizeof(l) for l in listoflists])
8000072000

所以,这符合预期。

另一方面,保留和填充长列表需要一段时间(大约 10 秒)。另外,退出 python 需要一段时间。 numpy 也是如此:

>>> a = numpy.empty((1000,1000000))
>>> a[:] = 1.0
>>> a.nbytes
8000000000

(字节数并不完全可靠,因为对象本身需要一些空间用于其元数据等。必须有指向内存块开头的指针、数据类型、数组形状等)

这需要更少的时间。数组的创建几乎是瞬时的,插入数字可能需要一两秒。分配和释放大量小内存块非常耗时,虽然在 64 位机器中不会导致碎片问题,但分配大数据 block 仍然要容易得多。

如果您有大量可以放入数组的数据,那么您需要一个不使用numpy的充分理由。

关于python - 在Python中生成非常大的二维数组?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24455445/

相关文章:

python - 仅使用广播从指定列向量处的矩阵中减去列向量

Python:我不想解压文件夹,只想将特定文件保存到输出文件夹。我没有得到预期的输出

来自 R 的 do.call(rbind, lapply()) 的 Python 等价物

java - 如何将二维字符串数组转换为一维字符串数组?

c - 二维矩阵旋转与双线性插值

matlab - 将三角矩阵映射到向量

python - Flask-SQLAlchemy 多对多连接条件

python - 如何从 python 中编译的正则表达式模式中获取模式字符串?

php - MySQL - 从序列化数组执行 JOIN?

java - 展平不均匀数组 - 越界异常错误