93

NumPy是一个非常有用的库,通过使用它,我发现它能够轻松处理非常大(10000 x 10000)的矩阵,但开始与任何更大的矩阵作斗争(试图创建一个 50000 x 50000 的矩阵失败)。显然,这是因为大量的内存需求。

有没有办法以某种方式(没有几 TB 的 RAM)在 NumPy 中本地创建巨大的矩阵(比如 100 万乘 100 万)?

4

11 回答 11

93

PyTables 和 NumPy 是要走的路。

PyTables 将以 HDF 格式将数据存储在磁盘上,并可选择压缩。我的数据集经常得到 10 倍的压缩,这在处理数千万或数亿行时非常方便。它也非常快;我 5 岁的笔记本电脑可以以 1,000,000 行/秒的速度处理类似 SQL 的 GROUP BY 聚合的数据。对于基于 Python 的解决方案来说还不错!

再次以 NumPy 重新数组的形式访问数据非常简单:

data = table[row_from:row_to]

HDF 库负责读取相关数据块并转换为 NumPy。

于 2009-06-30T09:11:55.750 回答
57

numpy.arrays 意味着存在于内存中。如果您想使用大于 RAM 的矩阵,则必须解决这个问题。您至少可以采用两种方法:

  1. 尝试使用矩阵具有的任何特殊结构的更有效的矩阵表示。例如,正如其他人已经指出的那样,稀疏矩阵(有很多零的矩阵)有有效的数据结构,比如scipy.sparse.csc_matrix.
  2. 修改您的算法以处理子矩阵。您只能从磁盘读取当前正在计算中使用的矩阵块。设计为在集群上运行的算法通常按块工作,因为数据分散在不同的计算机上,并且仅在需要时通过。例如,矩阵乘法的 Fox 算法(PDF 文件)
于 2009-06-28T02:53:45.100 回答
31

您应该能够使用 numpy.memmap 对磁盘上的文件进行内存映射。使用较新的 python 和 64 位机器,您应该拥有必要的地址空间,而无需将所有内容加载到内存中。操作系统应该只处理将部分文件保留在内存中。

于 2009-06-28T01:46:24.770 回答
24

要处理稀疏矩阵,您需要scipy位于其之上的包——有关为您提供的稀疏矩阵选项的更多详细信息,numpy请参见此处scipy

于 2009-06-28T02:23:40.153 回答
11

Stefano Borini 的帖子让我了解了这种事情已经走了多远。

就是这个。 它似乎基本上可以满足您的需求。HDF5 将允许您存储非常大的数据集,然后以与 NumPy 相同的方式访问和使用它们。

于 2009-06-28T02:54:20.373 回答
6

确保您使用的是 64 位操作系统和 64 位版本的 Python/NumPy。请注意,在 32 位架构上,您通常可以寻址 3GB 的内存(内存映射 I/O 等丢失了大约 1GB)。

使用 64 位和大于可用 RAM 的事物阵列,您可以摆脱虚拟内存,但如果必须交换,事情会变得更慢。此外,内存映射(参见 numpy.memmap)是一种处理磁盘上的大文件而不将它们加载到内存中的方法,但同样,您需要有一个 64 位的地址空间才能使用它。PyTables 也会为您完成大部分工作。

于 2009-08-19T00:27:02.703 回答
5

这有点阿尔法,但http://blaze.pydata.org/似乎正在努力解决这个问题。

于 2013-02-05T00:58:35.953 回答
4

有时,一种简单的解决方案是为您的矩阵项使用自定义类型。根据您需要的数字范围,您可以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
于 2016-10-03T22:09:11.877 回答
3

您是否在问如何在没有 TB 内存的情况下处理 2,500,000,000 个元素的矩阵?

在没有 80 亿字节 RAM 的情况下处理 20 亿个项目的方法是不将矩阵保存在内存中。

这意味着更复杂的算法可以从文件系统中分段获取它。

于 2009-06-28T02:32:13.007 回答
1

通常当我们处理大型矩阵时,我们将它们实现为稀疏矩阵

我不知道 numpy 是否支持稀疏矩阵,但我发现了这个

于 2009-06-28T00:45:43.003 回答
1

据我对 numpy 的了解,不,但我可能是错的。

我可以向您推荐这个替代解决方案:将矩阵写入磁盘并以块的形式访问它。我建议你使用 HDF5 文件格式。如果您需要它透明,您可以重新实现 ndarray 接口以将磁盘存储的矩阵分页到内存中。如果您修改数据以将它们同步回磁盘上,请务必小心。

于 2009-06-28T00:46:30.787 回答