如何从一个稀疏稀疏矩阵中找回块?

时间:2018-12-01 18:55:07

标签: python scipy sparse-matrix

经过一些矢量化计算后,我得到了一个稀疏的块矩阵,所有结果都堆积在相同大小的块中。

>>> A = [[1, 1],
...      [1, 1]]
>>> B = [[2, 2],
...      [2, 2]]
>>> C = [[3, 3],
...      [3, 3]]
>>> results = scipy.sparse.block_diag(A, B, C)
>>> print(results.toarray())
[[1 1 0 0 0 0]
 [1 1 0 0 0 0]
 [0 0 2 2 0 0]
 [0 0 2 2 0 0]
 [0 0 0 0 3 3]
 [0 0 0 0 3 3]]

如果需要通过提供形状(2,2),如何有效地取回这些数组A,B,C?

2 个答案:

答案 0 :(得分:0)

In [177]: >>> A = [[1, 1],
     ...: ...      [1, 1]]
     ...: >>> B = [[2, 2],
     ...: ...      [2, 2]]
     ...: >>> C = [[3, 3],
     ...: ...      [3, 3]]
     ...: >>> results = sparse.block_diag([A, B, C])
     ...:      
In [178]: results
Out[178]: 
<6x6 sparse matrix of type '<class 'numpy.int64'>'
    with 12 stored elements in COOrdinate format>

block_diag不保留输入。而是创建coo格式的矩阵,表示整个矩阵,而不是片段。

In [194]: results.data
Out[194]: array([1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3], dtype=int64)
In [195]: results.row
Out[195]: array([0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5], dtype=int32)
In [196]: results.col
Out[196]: array([0, 1, 0, 1, 2, 3, 2, 3, 4, 5, 4, 5], dtype=int32)


In [179]: results.A
Out[179]: 
array([[1, 1, 0, 0, 0, 0],
       [1, 1, 0, 0, 0, 0],
       [0, 0, 2, 2, 0, 0],
       [0, 0, 2, 2, 0, 0],
       [0, 0, 0, 0, 3, 3],
       [0, 0, 0, 0, 3, 3]], dtype=int64)

block_diag将数组传递到sparse.bmat。依次从每个矩阵中创建一个coo矩阵,然后将coo属性合并为3个数组,这些数组是全局稀疏矩阵的输入。


还有另一种稀疏格式bsr可以保留块(直到转换为csr进行计算),但是我不得不做实验才能看到这种情况。

让我们从该bsr results中创建一个coo

In [186]: bresults = sparse.bsr_matrix(results)
In [187]: bresults
Out[187]: 
<6x6 sparse matrix of type '<class 'numpy.int64'>'
    with 12 stored elements (blocksize = 2x2) in Block Sparse Row format>
In [188]: bresults.blocksize
Out[188]: (2, 2)
In [189]: bresults.data
Out[189]: 
array([[[1, 1],
        [1, 1]],

       [[2, 2],
        [2, 2]],

       [[3, 3],
        [3, 3]]], dtype=int64)

因此,它可以推断出是否有块,如您所愿。

In [191]: bresults.indices
Out[191]: array([0, 1, 2], dtype=int32)
In [192]: bresults.indptr
Out[192]: array([0, 1, 2, 3], dtype=int32)

所以它像csr一样的存储,但是data是以块的形式排列的。

可能无需您A,B,C的中介就可以从您的block_diag来构建它,但是我不得不更多地研究文档。

答案 1 :(得分:-1)

这是一个有趣的小问题。

我认为没有一个函数可以一并解决这个问题,但是有一种方法可以通过编程来实现。

查看打印出什么res.data,我在这里使用它。

这在形状相同的情况下有效。

from scipy.sparse import block_diag

a = [[1, 2, 4],
    [3, 4, 4]]
b = [[2, 2, 1],
    [2, 2, 1]]
c = [[3, 3, 6],
    [3, 3, 6]]

res = block_diag((a, b, c))

def goBack(res, shape):
    s = shape[0]*shape[1]
    num = int(len(res.data)/s)
    for i in range (num):
        mat = res.data[i*s:(i+1)*s].reshape(shape)
        print(mat)

goBack(res, [2,3])

输出:

[[1 2 4]
 [3 4 4]]
[[2 2 1]
 [2 2 1]]
[[3 3 6]
 [3 3 6]]

编辑:

好的,当提供的矩阵的任何元素为零时,这将不起作用,因为那样,它将不会计入res.data中。

此外,算了,cleb提供的链接应该会对您有所帮助。