经过一些矢量化计算后,我得到了一个稀疏的块矩阵,所有结果都堆积在相同大小的块中。
>>> 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?
答案 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提供的链接应该会对您有所帮助。