2014-12-24 3 views
2

Я хочу, чтобы разделить разреженные матрицы Scipy на части, и они вернули их вместе.Разделите разреженные матрицы и положите их обратно

Например, начиная с разреженным массивом:

# 0 1 0 
# 3 0 5 
# 0 7 0 

разделить его на 6 разреженных массивов:

# 0 1 0 
# 3 0 5 
# 
# 0 7 0 

Другими словами, я хочу функции split_sparse и merge_sparse такие, что после испытания проходит:

# Humpty Dumpy sat on a wall 
mat = np.arange(9) 
mat[::2] = 0 
mat=mat.reshape(3, 3) 
mat=csr_matrix(mat) 

# Humpy dumpty had a great fall 
row_divs = [2] 
col_divs = [1, 2] 
split_mat = split_sparse(mat, row_divs, col_divs) 

sparse_eq = lambda x, y: (x-y).nnz == 0 

# All the kings horses and all the kings men 
assert sparse_eq(split_mat[0, 0], csr_matrix([[0], [3]])) 
assert sparse_eq(split_mat[0, 1], csr_matrix([[1], [0]])) 
assert sparse_eq(split_mat[0, 2], csr_matrix([[0], [5]])) 
assert sparse_eq(split_mat[1, 0], csr_matrix([[0]])) 
assert sparse_eq(split_mat[1, 1], csr_matrix([[7]])) 
assert sparse_eq(split_mat[1, 2], csr_matrix([[0]])) 

# Pooled their efforts and put Humpy together again. 
assert sparse_eq(merge_sparse(split_mat), mat) 

ответ

0

Отличный вопрос, как обычно, Питер. Вот ваш ответ.

Редактировать: Как указано в hpaulj, решение не имеет никакого отношения к разреженным массивам, оно просто использует тот факт, что scipy уже имеет эффективные реализации нарезки, hstack и vstack.

from scipy.sparse import hstack, vstack 
import numpy as np 


def split_sparse(mat, row_divs = [], col_divs = []): 
    ''' 
    mat is a sparse matrix 
    row_divs is a list of divisions between rows. N row_divs will produce N+1 rows of sparse matrices 
    col_divs is a list of divisions between cols. N col_divs will produce N+1 cols of sparse matrices 

    return a 2-D array of sparse matrices 
    ''' 
    row_divs = [None]+row_divs+[None] 
    col_divs = [None]+col_divs+[None] 

    mat_of_mats = np.empty((len(row_divs)-1, len(col_divs)-1), dtype = type(mat)) 
    for i, (rs, re) in enumerate(zip(row_divs[:-1], row_divs[1:])): 
     for j, (cs, ce) in enumerate(zip(col_divs[:-1], col_divs[1:])): 
      mat_of_mats[i, j] = mat[rs:re, cs:ce] 

    return mat_of_mats 


def merge_sparse(mat_of_mats): 
    ''' 
    mat_of_mats is a 2D array of sparse matrices where: 
     mat_of_mats[i, j1].shape[0] == mat_of_mats[i, j2].shape[0] for any j1, j2 
     mat_of_mats[i1, j].shape[1] == mat_of_mats[i2, j].shape[1] for any i1, i2 
    i.e. They can be tiled together. 

    Merge them together into a single sparse matrix. 
    ''' 
    rows = [hstack(m) for m in mat_of_mats] 
    newmat = vstack(rows) 
    return newmat 
+0

С соответствующими 'hstack' и' vstack' похоже, что это будет работать и с плотными массивами. Он использует тот факт, что некоторые разреженные форматы реализуют срез и индексирование почти так же, как и плотные массивы ('mat [rs: re, cs: ce]'). – hpaulj

Смежные вопросы