Какой формат разреженной матрицы предпочтительнее для построения блочных матриц - PullRequest
1 голос
/ 07 марта 2019

Я хотел бы построить блочную матрицу, используя один из соответствующих форматов scipy .В конечном итоге, матрица должна быть преобразована в CSC.

Я, по сути, получаю блоки в виде (плотных) массивов с номерами (имеющих ndim == 2) или иногда в качестве разреженных тождеств.Для каждого подмножества строк (сверху вниз) я добавляю соответствующие блоки слева направо.В настоящее время я создаю матрицу, а затем назначаю блоки на основе фрагментов индексов.

Мои вопросы (относительно производительности) следующие:

  1. Желательно ли использовать нарезку или следуетВместо этого я использую scipy.sparse.bmat?
  2. Если я использую срезы, какой тип матрицы мне следует использовать для вставки блоков (я назначаю срезы вида M[a:b,:] и M[:,a:b])?

1 Ответ

1 голос
/ 07 марта 2019

Я не знаю, насколько эффективны методы 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]]
...