简体   繁体   English

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

[英]How to get the blocks back from a scipy sparse block matrix?

After some vectorized calculations, I get a sparse block matrix with all my results stacked in blocks of same size. 经过一些矢量化计算后,我得到了一个稀疏的块矩阵,所有结果都堆积在相同大小的块中。

>>> 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]]

How can I get back these arrays A,B,C in an efficient way, if necessery by providing their shape (2,2)? 如果需要通过提供形状(2,2),如何有效地取回这些数组A,B,C?

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 does not preserve the inputs; block_diag不保留输入; rather it creates coo format matrix, representing the whole matrix, not the pieces. 而是创建了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 pass the arrays to sparse.bmat . block_diag将数组传递给sparse.bmat That in turn makes a coo matrix from each, and then merges the coo attributes into 3 arrays, which are inputs to the global sparse matrix. 依次从每个矩阵中创建一个coo矩阵,然后将coo属性合并为3个数组,这些数组是全局稀疏矩阵的输入。


There is another sparse format bsr that may preserve the blocks (until conversion to csr for calculation), but I'll have to experiment to see that's the case. 还有另一种稀疏格式bsr可以保留块(直到转换为csr以进行计算),但是我必须做试验才能看到这种情况。

Let's make a bsr from that results coo : 让我们从results cooresults一个bsr

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)

So it deduces that there are blocks, just as you desired. 因此,它可以推断出您所希望的存在障碍。

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)

So it's a csr like storage, but with the data arranged in blocks. 因此,这类似于csr存储,但是data以块的形式排列。

It may be possible to construct this from your A,B,C without the block_diag intermediary, but I'd have to look at the docs more. 无需block_diag中介,就可以从您的A,B,C构造它,但是我不得不更多地研究文档。

that's a funny little problem. 这是一个有趣的小问题。

I don't think there is a function that solves this in one line, but there's a way to do it programmatically. 我认为没有一个函数可以一口气解决这个问题,但是有一种方法可以通过编程实现。

Check out what res.data prints out, I use it here. 看看打印出什么res.data,我在这里用它。

This works when shapes are all the same. 当形状都相同时,此方法有效。

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])

Output: 输出:

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

Edit: 编辑:

Okay, this does not work when any of the elements of the provided matrices is zero, as then it would not be counted in res.data. 好的,当提供的矩阵的任何元素为零时,这将不起作用,因为这样就不会将其计入res.data中。

Also, forget it, the link provided by cleb should help you. 另外,算了,cleb提供的链接应该可以为您提供帮助。

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

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