NumPy是一个非常有用的库,通过使用它,我发现它能够轻松处理非常大(10000 x 10000)的矩阵,但开始与任何更大的矩阵作斗争(试图创建一个 50000 x 50000 的矩阵失败)。显然,这是因为大量的内存需求。
有没有办法以某种方式(没有几 TB 的 RAM)在 NumPy 中本地创建巨大的矩阵(比如 100 万乘 100 万)?
PyTables 和 NumPy 是要走的路。
PyTables 将以 HDF 格式将数据存储在磁盘上,并可选择压缩。我的数据集经常得到 10 倍的压缩,这在处理数千万或数亿行时非常方便。它也非常快;我 5 岁的笔记本电脑可以以 1,000,000 行/秒的速度处理类似 SQL 的 GROUP BY 聚合的数据。对于基于 Python 的解决方案来说还不错!
再次以 NumPy 重新数组的形式访问数据非常简单:
data = table[row_from:row_to]
HDF 库负责读取相关数据块并转换为 NumPy。
numpy.array
s 意味着存在于内存中。如果您想使用大于 RAM 的矩阵,则必须解决这个问题。您至少可以采用两种方法:
scipy.sparse.csc_matrix
.您应该能够使用 numpy.memmap 对磁盘上的文件进行内存映射。使用较新的 python 和 64 位机器,您应该拥有必要的地址空间,而无需将所有内容加载到内存中。操作系统应该只处理将部分文件保留在内存中。
要处理稀疏矩阵,您需要scipy
位于其之上的包——有关为您提供的稀疏矩阵选项的更多详细信息,numpy
请参见此处scipy
。
确保您使用的是 64 位操作系统和 64 位版本的 Python/NumPy。请注意,在 32 位架构上,您通常可以寻址 3GB 的内存(内存映射 I/O 等丢失了大约 1GB)。
使用 64 位和大于可用 RAM 的事物阵列,您可以摆脱虚拟内存,但如果必须交换,事情会变得更慢。此外,内存映射(参见 numpy.memmap)是一种处理磁盘上的大文件而不将它们加载到内存中的方法,但同样,您需要有一个 64 位的地址空间才能使用它。PyTables 也会为您完成大部分工作。
这有点阿尔法,但http://blaze.pydata.org/似乎正在努力解决这个问题。
有时,一种简单的解决方案是为您的矩阵项使用自定义类型。根据您需要的数字范围,您可以dtype
为您的物品使用手册,特别是更小的手册。因为 Numpy 默认考虑对象的最大类型,这在许多情况下可能是一个有用的想法。这是一个例子:
In [70]: a = np.arange(5)
In [71]: a[0].dtype
Out[71]: dtype('int64')
In [72]: a.nbytes
Out[72]: 40
In [73]: a = np.arange(0, 2, 0.5)
In [74]: a[0].dtype
Out[74]: dtype('float64')
In [75]: a.nbytes
Out[75]: 32
并使用自定义类型:
In [80]: a = np.arange(5, dtype=np.int8)
In [81]: a.nbytes
Out[81]: 5
In [76]: a = np.arange(0, 2, 0.5, dtype=np.float16)
In [78]: a.nbytes
Out[78]: 8
您是否在问如何在没有 TB 内存的情况下处理 2,500,000,000 个元素的矩阵?
在没有 80 亿字节 RAM 的情况下处理 20 亿个项目的方法是不将矩阵保存在内存中。
这意味着更复杂的算法可以从文件系统中分段获取它。
据我对 numpy 的了解,不,但我可能是错的。
我可以向您推荐这个替代解决方案:将矩阵写入磁盘并以块的形式访问它。我建议你使用 HDF5 文件格式。如果您需要它透明,您可以重新实现 ndarray 接口以将磁盘存储的矩阵分页到内存中。如果您修改数据以将它们同步回磁盘上,请务必小心。