简体   繁体   English

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

[英]Large matrix multiplication in Python - what is the best option?

I have two boolean sparse square matrices of c. 我有两个布尔稀疏的方形矩阵c。 80,000 x 80,000 generated from 12BM of data (and am likely to have orders of magnitude larger matrices when I use GBs of data). 从12BM数据生成80,000 x 80,000(当我使用GB数据时,可能会有更大数量级的矩阵)。

I want to multiply them (which produces a triangular matrix - however I dont get this since I don't limit the dot product to yield a triangular matrix). 我想将它们相乘(它产生一个三角形矩阵 - 但是我没有得到这个,因为我不限制点积产生三角矩阵)。

I am wondering what the best way of multiplying them is (memory-wise and speed-wise) - I am going to do the computation on a m2.4xlarge AWS instance which has >60GB of RAM. 我想知道它们的最佳乘法方式是什么(内存方式和速度方式) - 我将在m2.4xlarge AWS实例上进行计算,该实例具有> 60GB的RAM。 I would prefer to keep the calc in RAM for speed reasons. 出于速度原因,我宁愿将计算结果保留在RAM中。

I appreciate that SciPy has sparse matrices and so does h5py, but have no experience in either. 我很欣赏SciPy有稀疏矩阵,h5py也是如此,但两者都没有经验。

Whats the best option to go for? 什么是最好的选择?

Thanks in advance 提前致谢

UPDATE: sparsity of the boolean matrices is <0.6% 更新:布尔矩阵的稀疏度<0.6%

If your matrices are relatively empty it might be worthwhile encoding them as a data structure of the non-False values. 如果你的矩阵相对空,那么将它们编码为非False值的数据结构可能是值得的。 Say a list of tuples describing the location of the non-False values. 说一个描述非False值位置的元组列表。 Or a dictionary with the tuples as the keys. 或者以元组为键的字典。

If you use eg a list of tuples you could use a list comprehension to find the items in the second list that can be multiplied with an element from the first list. 如果使用例如元组列表,则可以使用列表推导来查找第二个列表中的项目,这些项目可以与第一个列表中的元素相乘。

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]

-- EDITED TO SATISFY BELOW COMMENT / DOWNVOTER -- - 编辑到满意的评论/ DOWNVOTER -

You're asking how to multiply matrices fast and easy. 你问的是如何快速和简单地乘法矩阵。

SOLUTION 1 : This is a solved problem: use numpy. 解决方案1 :这是一个已解决的问题:使用numpy。 All these operations are easy in numpy, and since they are implemented in C, are rather blazingly fast. 所有这些操作都很简单,并且由于它们是用C实现的,因此速度非常快。

also see: 另见:

SciPy and Numpy have sparse matrices and matrix multiplication. SciPy和Numpy具有稀疏矩阵和矩阵乘法。 It doesn't use much memory since (at least if I wrote it in C) it probably uses linked lists, and thus will only use the memory required for the sum of the datapoints, plus some overhead. 它没有使用太多内存,因为(至少如果我用C编写它)它可能使用链表,因此只会使用数据点总和所需的内存,加上一些开销。 And, it will almost certainly be blazingly fast compared to pure python solution. 而且,与纯python解决方案相比,它几乎肯定会非常快。

SOLUTION 2 解决方案2

Another answer here suggests storing values as tuples of (x, y), presuming value is False unless it exists, then it's true. 这里的另一个答案建议将值存储为(x,y)的元组,假设值为False,除非它存在,那么它是真的。 Alternate to this is a numeric matrix with (x, y, value) tuples. 替代它是具有(x,y,value)元组的数字矩阵。

REGARDLESS: Multiplying these would be Nasty time-wise: find element one, decide which other array element to multiply by, then search the entire dataset for that specific tuple, and if it exists, multiply and insert the result into the result matrix. 无冗余:将这些乘以时间是令人讨厌的:找到元素1,确定要乘以哪个其他数组元素,然后在整个数据集中搜索该特定元组,如果存在,则将结果相乘并将结果插入到结果矩阵中。

SOLUTION 3 ( PREFERRED vs. Solution 2, IMHO ) 解决方案3 (首选与解决方案2,恕我直言)

I would prefer this because it's simpler / faster. 我更喜欢这个,因为它更简单/更快。

Represent your sparse matrix with a set of dictionaries. 用一组字典表示稀疏矩阵。 Matrix one is a dict with the element at (x, y) and value v being (with x1,y1, x2,y2, etc.): 矩阵1是一个dict,元素位于(x,y),值v为(x1,y1,x2,y2等):

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

Since a Python dict lookup is O(1) (okay, not really, probably closer to log(n)), it's fast. 由于Python dict查找是O(1)(好吧,不是真的,可能更接近log(n)),它很快。 This does not require searching the entire second matrix's data for element presence before multiplication. 这不需要在乘法之前搜索整个第二矩阵的数据以查找元素存在。 So, it's fast. 所以,它很快。 It's easy to write the multiply and easy to understand the representations. 编写乘法和易于理解的表示很容易。

SOLUTION 4 (if you are a glutton for punishment) 解决方案4 (如果你是一个贪婪的惩罚)

Code this solution by using a memory-mapped file of the required size. 使用所需大小的内存映射文件对此解决方案进行编码。 Initialize a file with null values of the required size. 使用所需大小的空值初始化文件。 Compute the offsets yourself and write to the appropriate locations in the file as you do the multiplication. 自己计算偏移量并在进行乘法时写入文件中的相应位置。 Linux has a VMM which will page in and out for you with little overhead or work on your part. Linux有一个VMM,它可以为您提供进出页面,只需很少的开销或您的工作。 This is a solution for very, very large matrices that are NOT SPARSE and thus won't fit in memory. 这是非常非常大的矩阵的解决方案,它不是稀疏的 ,因此不适合存储器。

Note this solves the complaint of the below complainer that it won't fit in memory. 请注意,这解决了以下投诉人的抱怨 ,即它不适合记忆。 However, the OP did say sparse , which implies very few actual datapoints spread out in giant arrays, and Numpy / SciPy handle this natively and thus nicely (lots of people at Fermilab use Numpy / SciPy regularly, I'm confident the sparse matrix code is well tested). 然而,OP确实说稀疏 ,这意味着很少有实际的数据点在巨型阵列中扩散,Numpy / SciPy原生处理这个问题很好(很多人在Fermilab经常使用Numpy / SciPy,我对确保稀疏矩阵代码很有信心)经过充分测试)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM