实例化大型稀疏矩阵以进行赋值操作

问题描述 投票:0回答:2

如果要实例化一个大型布尔稀疏矩阵,以便以后在某些索引处分配值,初始化它的最佳方法是什么?

例如,如果要在MATLAB上用10000个填充元素初始化20000000 X 7000逻辑稀疏矩阵(不提及非零元素的位置,我将使用以下语法:

Matrix=logical(sparse([],[],[],20000000,7000,10000))

我以后对分配非零值没有速度限制。

在Python上,如果我将其初始化为CSR矩阵,则矩阵的创建非常快。

Matrix=csr_matrix((20000000, 7000), dtype=bool)

CPU times: user 860 µs, sys: 2.43 ms, total: 3.29 ms
Wall time: 9.72 ms

但是,当我无法有效地将值分配给CSR_Matrix时,该操作将非常缓慢,并且会看到内置警告。

如果我尝试将其初始化为LIL矩阵:

Matrix=lil_matrix((20000000, 7000), dtype=bool)

CPU times: user 12.4 s, sys: 624 ms, total: 13 s
Wall time: 13 s

或将csr_matrix转换为lil_matrix:

Matrix=csr_matrix((20000000, 7000), dtype=bool)
Matrix=Matrix.tolil()

CPU times: user 26.8 s, sys: 734 ms, total: 27.5 s
Wall time: 27.5 s

初始化花费大量时间。

是否有任何方法可以加快LIL矩阵的初始化?如果不是,我可以使用哪种稀疏矩阵格式来加快将非零元素分配给此类矩阵的速度?

python matlab numpy scipy sparse-matrix
2个回答
0
投票

如果您需要常规的增量索引访问,dok_matrix可能是您最好的选择。

通常在转换为csc,csr(代数运算通常需要这些东西)之前,先使用它进行构造(在某些情况下它可能会发光)。

编辑:下面的大多数内容集中于初始化+填充+之后需要执行的所有操作所需的累积时间。

根据您的情况:dok_matrix的初始化应该非常即时

...

允许对各个元素进行有效的O(1)访问。不允许重复。构造后可以有效地转换为coo_matrix。

话虽如此,这还取决于您的工作流程和省略的代码。给定某种结构(python-)无环任务相关的工作流肯定可以击败一般(python-)循环一次添加一个元素。通常,这涉及到coo_matrix

在某些情况下,对于某些工作流:您根本没有任何初始化时间,因为您没有创建先验矩阵,而是仅在一批创建矩阵之前收集所需的任何东西。不确定如何适应您的计算模型(这有点奇怪:初始化时间受限制;进一步的使用是[[免费)]


0
投票
我相当早以前就使用过MATLAB稀疏模型。当时,您使用[]创建了一个稀疏矩阵

S = sparse(i,j,v,m,n)

其中i,j,v,其中矩阵标识非零值的

全部

。不存在为更多非零预分配“空间”的额外nz参数。scipy中,等效为

S = sparse.csc_matrix((v, (i,j)), m, n)

再次,v,i,j是完全定义的数组。没有任何nz预分配选项。实际上,考虑到属性是如何存储的,我看不到预分配将如何工作或不会带来好处。

正如您所发现的,尝试以csc/csr格式定义非零值很慢,并且会产生警告。 lil/dok旨在使迭代加法更快。

csr创建时间取决于初始非零值的数量,而仅取决于形状(indptr数组的大小取决于行数)。通常,我们不必担心lil的初始化时间,但是有了20000000行,我就能明白为什么要花一些时间。它必须创建两个带有空列表元素的dtype对象数组。

无论如何,请避免使用增量定义。从您的源创建i,j,v数组,然后构建矩阵。

© www.soinside.com 2019 - 2024. All rights reserved.