是否存在对scipy.linalg.block_diag的反向操作?

yyhrrdl8  于 2022-11-10  发布在  其他
关注(0)|答案(1)|浏览(114)

我知道scipy提供了一个方便的函数,可以将数组列表转换为块对角矩阵,例如。

>>> from scipy.linalg import block_diag
>>> A = [[1, 0],
         [0, 1]]
>>> B = [[3, 4, 5],
         [6, 7, 8]]
>>> C = [[7]]
>>> D = block_diag(A, B, C)
>>> D
array([[1, 0, 0, 0, 0, 0],
       [0, 1, 0, 0, 0, 0],
       [0, 0, 3, 4, 5, 0],
       [0, 0, 6, 7, 8, 0],
       [0, 0, 0, 0, 0, 7]])

有没有相反的操作?即取一个块对角矩阵和一个块大小列表,并分解为一个数组列表。

a, b, c = foo(D, block_sizes=[(2,2), (2,3), (1,1)])

如果没有方便的内置方法来实现这一点,有没有比循环输入数组更好(性能更高)的实现呢?简单的实现可能如下所示:

def foo(matrix, block_sizes):
    result = []
    curr_row, curr_col = 0, 0 
    for nrows, ncols in block_sizes:
        result.append(matrix[curr_row:curr_row + nrows, curr_col:curr_col + ncols])
        curr_row += nrows
        curr_col += ncols
    return result
cgfeq70w

cgfeq70w1#

查看block_diag的代码:
核心部分分配一个out数组,然后迭代地将块分配给它:

out = np.zeros(np.sum(shapes, axis=0), dtype=out_dtype)
r, c = 0, 0
for i, (rr, cc) in enumerate(shapes):
    out[r:r + rr, c:c + cc] = arrs[i]
    r += rr
    c += cc

你是在想象更“有表现力”的东西吗?
你想要的是一个形状不同的数组列表。如果没有某种(python级别的)迭代,你怎么得到这些数组呢?
看一下np.split(及其变体)的代码,它也是迭代的,用多个切片生成一个数组列表。

相关问题