如何对稀疏矩阵列表求和?

Posted

技术标签:

【中文标题】如何对稀疏矩阵列表求和?【英文标题】:How to sum a list of sparse matrices? 【发布时间】:2022-01-03 11:35:30 【问题描述】:

我试图弄清楚如何有效地将存储在列表中的 .csr_matrix 稀疏矩阵求和。问题来了:

List_=list_of_sparse matrices
I tried the following
result=np.sum(List_)

但我遇到了错误!

我该怎么做?任何帮助将不胜感激

【问题讨论】:

如果您需要真正的帮助,请提供一个实际示例(例如minimal reproducible example)。还用回溯显示错误!!!也就是说,稀疏矩阵不是为有效加法而设计的。不改变稀疏性的数学是可以的,因为它可以专注于data 属性。矩阵乘法也很不错。但是像 sum 这样的事情需要弄清楚非零匹配的位置等等。 一种可能性是将所有矩阵转换为coo 格式,然后连接它们的属性(行、列、数据)。用这些创建一个新的coo,并让转换为csr 执行添加。 【参考方案1】:

你可以循环列表:

import numpy as np

List_ = [
    np.matrix([[0,0,0],[0,1,0],[0,0,0]]),
    np.matrix([[0,1,0],[0,0,0],[0,0,0]]),
    np.matrix([[0,0,0],[0,0,0],[0,1,0]]),
]

sum_in = np.matrix(
    [[0,0,0],[0,0,0],[0,0,0]]
)

for mat in List_:
    sum_in += mat

print(sum_in)

【讨论】:

感谢@Ammar,但是如何为稀疏矩阵创建 sum_in? 您可能需要事先将其转换为完整矩阵或查看 scipy 包 docs.scipy.org/doc/scipy/reference/sparse.html ***.com/questions/36969886/…【参考方案2】:

例如,您有一个这样的稀疏矩阵列表:

from scipy.sparse import csr_matrix
import numpy as np
np.random.seed(111)

List_ = [csr_matrix(np.random.binomial(1,0.5,(2,2))) for i in range(3)]

如果你的数组很大,尽量不要把它转成dense(内存问题),已经有加法的方法,所以只需要reduce即可:

from functools import reduce
result = reduce(lambda x,y:x+y,List_)
result.toarray()
array([[1, 0],
       [1, 1]])

正如@AmmarAslam 所说,您可以将其转换为密集和求和:

[i.toarray() for i in List_]
[array([[1, 0],
    [0, 1]]),
 array([[0, 0],
        [0, 0]]),
 array([[0, 0],
        [1, 0]])]

总结起来就是:

np.add.reduce([i.toarray() for i in List_])

array([[1, 0],
       [1, 1]])

【讨论】:

以上是关于如何对稀疏矩阵列表求和?的主要内容,如果未能解决你的问题,请参考以下文章

如何加快稀疏数组加法

如何对存储为“压缩稀疏行”的矩阵进行稀疏矩阵索引?

embedding的理解

使用 int 列表进行稀疏矩阵切片

稀疏矩阵的压缩与还原

Numba 中的稀疏矩阵