非常大的使用Python和NumPy的matrix

NumPy是一个非常有用的库,使用它我发现它能够很容易地处理相当大(10000 x 10000)的matrix,但是开始与任何更大的(争取创build一个50000 x 50000matrix失败)。 显然,这是因为内存需求量大。

有没有办法以某种方式在NumPy中生成巨大的matrix(比如100万)?

PyTables和NumPy是要走的路。

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

作为NumPy再次访问数据就像下面这样简单:

data = table[row_from:row_to] 

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

numpy.array是为了生活在记忆中。 如果你想使用大于你的RAM的matrix,你必须解决这个问题。 至less有两种方法可以遵循:

  1. 尝试更有效的matrix表示 ,利用matrix所具有的任何特殊结构。 例如,正如其他人已经指出的那样,稀疏matrix(有很多零的matrix)的数据结构是有效的,比如scipy.sparse.csc_matrix
  2. 修改您的algorithm以处理子matrix 。 您只能从磁盘读取正在计算中使用的matrix块。 devise用于在群集上运行的algorithm通常是按块进行的,因为数据分散在不同的计算机上,只有在需要时才传递。 例如, 用于matrix乘法的Foxalgorithm(PDF文件) 。

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

要处理稀疏matrix,您需要位于numpy之上的scipy包 – 请参阅此处以获取有关scipy为您提供的稀疏matrix选项的更多详细信息。

斯特凡诺·博里尼(Stefano Borini)的文章让我看到了这种事情到底有多远。

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

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

使用64位和东西数组大于可用RAM,您可以使用虚拟内存,尽pipe事情会变慢,如果你必须交换。 此外,内存映射(请参阅numpy.memmap)是一种在磁盘上处理大文件而不将其加载到内存中的方式,但是您需要有一个64位地址空间才能使用,因此非常有用。 PyTables也会为你做大部分的工作。

你问如何处理没有TB的RAM的25亿元matrix?

处理20亿个没有80亿字节RAM的项目的方法是不把matrix保存在内存中。

这意味着更复杂的algorithm可以将其从文件系统中分离出来。

通常当我们处理大matrix时,我们将它们实现为稀疏matrix 。

我不知道numpy是否支持稀疏matrix,但是我find了。

就我所知的numpy而言,不,但我可能是错的。

我可以为你提供这种替代解决scheme:在磁盘上写入matrix并以大块的forms访问它。 我build议你HDF5文件格式。 如果你需要透明的话,你可以重新实现ndarray接口来将你的磁盘存储matrix分页到内存中。 如果修改数据以将其同步到磁盘上,请小心。

有时候一个简单的解决scheme是使用matrix项目的自定义types。 根据您需要的数字范围,您可以使用手动dtype和特别小的项目。 因为Numpy在默认情况下考虑了对象的最大types,所以在许多情况下这可能是一个有用的想法。 这里是一个例子:

 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 

并与自定义types:

 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