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

时间:2013-12-04 19:34:43

标签: python numpy sparse-matrix pytables h5py

我有两个布尔稀疏的方形矩阵c。从12BM数据生成80,000 x 80,000(当我使用GB数据时,可能会有更大数量级的矩阵)。

我想将它们相乘(产生一个三角形矩阵 - 但是我没有得到这个,因为我不限制点积产生三角矩阵)。

我想知道乘法的最佳方式是什么(内存方式和速度方式) - 我将在m2.4xlarge AWS实例上进行计算,该实例具有> 60GB的RAM。出于速度原因,我宁愿将计算结果保留在RAM中。

我很欣赏SciPy有稀疏矩阵,h5py也是如此,但两者都没有经验。

什么是最佳选择?

提前致谢

更新:布尔矩阵的稀疏度<0.6%

2 个答案:

答案 0 :(得分:1)

如果你的矩阵相对空,那么将它们编码为非False值的数据结构可能是值得的。说一个描述非False值位置的元组列表。或者以元组为键的字典。

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

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]

答案 1 :(得分:-1)

- 赞美以下评论/ DOWNVOTER -

您正在询问如何快速轻松地乘以矩阵。

解决方案1 ​​:这是一个已解决的问题:使用numpy。所有这些操作都很简单,并且由于它们是用C实现的,因此速度非常快。

另见:

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

解决方案2

这里的另一个答案建议将值存储为(x,y)的元组,假设值为False,除非它存在,那么它是真的。替代它是一个带有(x,y,value)元组的数字矩阵。

REGARDLESS:将这些乘以讨厌时间:找到元素1,决定要乘以哪个其他数组元素,然后在整个数据集中搜索该特定元组,如果存在,则乘以并将结果插入结果矩阵。

解决方案3 (首选与解决方案2,恕我直言)

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

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

matrixDictOne = { 'x1:y1' : v1, 'x2:y2': v2, ... }
matrixDictTwo = { 'x1:y1' : v1, 'x2:y2': v2, ... }

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

解决方案4 (如果你是一个受到侮辱的惩罚)

使用所需大小的内存映射文件对此解决方案进行编码。使用所需大小的空值初始化文件。自己计算偏移量并在进行乘法时写入文件中的相应位置。 Linux有一个VMM,它可以为您提供进出页面,只需很少的开销或您的工作。这是非常非常大的矩阵的解决方案 NOT SPARSE ,因此不适合内存。

请注意,解决了以下投诉人的投诉,它不适合记忆。然而,OP确实说稀疏,这意味着很少有实际的数据点在巨型数组中扩散,而Numpy / SciPy原生处理这个问题很好(很多人在Fermilab经常使用Numpy / SciPy,我我确信稀疏矩阵码经过了很好的测试。