Я не знаю, насколько эффективны методы scipy, но с использованием формата coo
довольно просто построить блочную матрицу вручную. Все, что нужно сделать, это собрать атрибуты row
, col
и data
блоков, добавить смещения блоков к координатам (т.е. row
и col
) и затем объединить:
import numpy as np
from scipy import sparse
from collections import namedtuple
from operator import attrgetter
submat = namedtuple('submat', 'row_offset col_offset block')
def join_blocks(blocks):
roff, coff, mat = zip(*blocks)
row, col, data = zip(*map(attrgetter('row', 'col', 'data'), mat))
row = [o + r for o, r in zip(roff, row)]
col = [o + c for o, c in zip(coff, col)]
row, col, data = map(np.concatenate, (row, col, data))
return sparse.coo_matrix((data, (row, col))).tocsr()
example = [*map(submat, range(0, 10, 2), range(8, -2, -2), map(sparse.coo_matrix, np.multiply.outer([6, 2, 1, 3, 4], [[1, 0], [-1, 1]])))]
print('Example:')
for sm in example:
print(sm)
print('\nCombined')
print(join_blocks(example).A)
Печать:
Example:
submat(row_offset=0, col_offset=8, block=<2x2 sparse matrix of type '<class 'numpy.int64'>'
with 3 stored elements in COOrdinate format>)
submat(row_offset=2, col_offset=6, block=<2x2 sparse matrix of type '<class 'numpy.int64'>'
with 3 stored elements in COOrdinate format>)
submat(row_offset=4, col_offset=4, block=<2x2 sparse matrix of type '<class 'numpy.int64'>'
with 3 stored elements in COOrdinate format>)
submat(row_offset=6, col_offset=2, block=<2x2 sparse matrix of type '<class 'numpy.int64'>'
with 3 stored elements in COOrdinate format>)
submat(row_offset=8, col_offset=0, block=<2x2 sparse matrix of type '<class 'numpy.int64'>'
with 3 stored elements in COOrdinate format>)
Combined
[[ 0 0 0 0 0 0 0 0 6 0]
[ 0 0 0 0 0 0 0 0 -6 6]
[ 0 0 0 0 0 0 2 0 0 0]
[ 0 0 0 0 0 0 -2 2 0 0]
[ 0 0 0 0 1 0 0 0 0 0]
[ 0 0 0 0 -1 1 0 0 0 0]
[ 0 0 3 0 0 0 0 0 0 0]
[ 0 0 -3 3 0 0 0 0 0 0]
[ 4 0 0 0 0 0 0 0 0 0]
[-4 4 0 0 0 0 0 0 0 0]]