Python中的大型矩阵乘法-最佳选项是什么?

Python中的大型矩阵乘法-最佳选项是什么?,python,numpy,sparse-matrix,pytables,h5py,Python,Numpy,Sparse Matrix,Pytables,H5py,我有两个c的布尔稀疏平方矩阵。80000 x 80000由12BM的数据生成(当我使用GBs的数据时,我的矩阵可能会大几个数量级) 我想把它们相乘(这会产生一个三角形矩阵——但是我不明白这一点,因为我不限制点积来产生一个三角形矩阵) 我想知道将它们相乘的最佳方法是什么(内存和速度)-我将在一个m2.4X大型AWS实例上进行计算,该实例的RAM大于60GB。出于速度原因,我更愿意将计算结果保存在RAM中 我很欣赏SciPy有稀疏矩阵,h5py也有稀疏矩阵,但在这两方面都没有经验 最好的选择是什么

我有两个c的布尔稀疏平方矩阵。80000 x 80000由12BM的数据生成(当我使用GBs的数据时,我的矩阵可能会大几个数量级)

我想把它们相乘(这会产生一个三角形矩阵——但是我不明白这一点,因为我不限制点积来产生一个三角形矩阵)

我想知道将它们相乘的最佳方法是什么(内存和速度)-我将在一个m2.4X大型AWS实例上进行计算,该实例的RAM大于60GB。出于速度原因,我更愿意将计算结果保存在RAM中

我很欣赏SciPy有稀疏矩阵,h5py也有稀疏矩阵,但在这两方面都没有经验

最好的选择是什么

提前谢谢


更新:布尔矩阵的稀疏性是若你们的矩阵是相对空的,那个么将它们编码为非假值的数据结构可能是值得的。说一个元组列表,描述非假值的位置。或者是以元组为键的字典

例如,如果您使用元组列表,您可以使用列表理解来查找第二个列表中可以与第一个列表中的元素相乘的项目

a = [(0,0), (3,7), (5,2)] # et cetera
b = ... # idem

for r, c in a:
    res = [(r, k) for j, k in b if k == j]
--编辑以满足下面的评论/DOWNVOTER--

你问的是如何快速简单地乘法矩阵

解决方案1:这是一个已解决的问题:使用numpy。所有这些操作在numpy中都很容易,而且因为它们是用C实现的,所以速度非常快

另见:

SciPy和Numpy具有稀疏矩阵和矩阵乘法。它不会使用太多内存,因为(至少如果我用C编写的话)它可能使用链表,因此只会使用数据点总和所需的内存,外加一些开销。而且,与纯python解决方案相比,它几乎肯定会非常快

解决方案2

这里的另一个答案建议将值存储为(x,y)的元组,假设值为False,除非它存在,否则它为true。另一种方法是使用(x,y,value)元组的数字矩阵

不管怎样:将这些元素相乘将是非常糟糕的时间:找到元素1,决定要与哪个数组元素相乘,然后在整个数据集中搜索该特定元组,如果它存在,则相乘并将结果插入结果矩阵

解决方案3(首选方案与解决方案2,IMHO)

我更喜欢这个,因为它更简单/更快

用一组字典表示稀疏矩阵。矩阵1是一个dict,元素位于(x,y),值v为(x1,y1,x2,y2等):

因为Python dict查找是O(1)(好的,不是真的,可能更接近log(n)),所以它很快。这不需要在乘法之前搜索整个第二个矩阵的数据中是否存在元素。所以,它很快。写乘法很容易,理解表示也很容易

解决方案4(如果你贪吃而受到惩罚)

使用所需大小的内存映射文件对此解决方案进行编码。使用所需大小的空值初始化文件。自己计算偏移量,并在执行乘法时写入文件中的适当位置。Linux有一个VMM,它可以为您进行页面输入和输出,并且开销很小,或者您自己也可以。这是一个非常非常大的矩阵的解决方案,这些矩阵不是稀疏的,因此不适合内存


请注意,此解决了以下投诉人的投诉,即它无法放入内存。然而,OP确实说了稀疏,这意味着在巨大的阵列中分布的实际数据点很少,Numpy/SciPy可以很好地处理这一点(Fermilab的许多人定期使用Numpy/SciPy,我相信稀疏矩阵代码经过了很好的测试)。

你将它们作为布尔数进行乘法吗,也就是说,结果是布尔型的?你的数据有多稀疏,1的百分比是多少?是的,我把它们作为布尔数乘以0,1,因此得到的矩阵中的数字是0或大于0的整数。我如何检查矩阵的稀疏性?你们生成了它们,你们可以从算法中知道。你可以用
sum()
检查一个数的数量,然后除以总大小(在你的例子中是6.4*10**9),布尔矩阵中0.6%的数字剩余部分为零。我不确定,但我认为结果一般不会稀疏,你将无法将其存储在几十GB的RAM中。无论如何,请检查scipy.sparse中的csr和csc稀疏格式。您阅读了问题了吗?OP问题中的矩阵可能太大,无法存储在RAM中。而且任何已知的矩阵乘法算法都不比O(n^2.7)好,O(n^2.7)对于OP来说是一个巨大的数字。不同意:稀疏矩阵不分配m*n的数组。它只分配实际元素数使用的内存。OP引用了一个非常大的稀疏矩阵。用Python编写稀疏矩阵可能很糟糕。由于SciPy/Numpy使用C语言优化的数组,可能是优化内存的链表数组,这是完全可能的。任何一个大部分为空的稀疏矩阵乘以另一个大部分为空的稀疏矩阵都应该绝对适合内存。此外,在linux系统上,VMM可以将内存映射到磁盘上,并且可以很好地工作。值得注意的是,scipy实际上并不是“在
C
中实现的”,它主要由
C++
FORTRAN
组成。Kevin,请注意,稀疏性是在0.6%的数据中指定的,这实际上并不是非常稀疏的。这就是为什么我认为,当数量级按规定增长时,8*106x8*106矩阵将在手边,它将包含0.006*6.4*1013=3.84*1011非零值,这是一个巨大的数字,无法放入内存中。以前的尺寸8*10**5是这方面的边界,等等
matrixDictOne = { 'x1:y1' : v1, 'x2:y2': v2, ... }
matrixDictTwo = { 'x1:y1' : v1, 'x2:y2': v2, ... }