scipy 如何用给定的基矩阵创建稀疏矩阵?

mcdcgff0  于 2022-11-10  发布在  其他
关注(0)|答案(2)|浏览(195)

我有下面的2 x 2矩阵
我想用2的幂展开这个矩阵。例如,维数为4的矩阵看起来像这样:
基本上,我希望在基矩阵中出现1的地方保留原始矩阵,而在基矩阵中出现0的地方填充零。在numpyscipy中有快速的方法吗?我希望能够将其扩展到2的任何幂,比如512或1024。

neekobn8

neekobn81#

对于2的幂的相对较小的值(比如最大为10),可以使用numpy block递归地将每个1替换为初始矩阵a

import numpy as np

a = np.array([[1, 0], [1, 1]])

def generate(a, k):
    z = np.zeros_like(a)
    result = a.copy()
    for _ in range(1, k):
        result = eval(f"np.block({str(result.tolist()).replace('1', 'a').replace('0', 'z')})")
    return result

k=3(8x8结果矩阵)generate(a, 3)的示例:

array([[1, 0, 0, 0, 0, 0, 0, 0],
       [1, 1, 0, 0, 0, 0, 0, 0],
       [1, 0, 1, 0, 0, 0, 0, 0],
       [1, 1, 1, 1, 0, 0, 0, 0],
       [1, 0, 0, 0, 1, 0, 0, 0],
       [1, 1, 0, 0, 1, 1, 0, 0],
       [1, 0, 1, 0, 1, 0, 1, 0],
       [1, 1, 1, 1, 1, 1, 1, 1]])
hi3rlvi2

hi3rlvi22#

您可以合并拼贴和重复组合使用。

>>> np.tile(arr, (2, 2))

array([[1, 0, 1, 0],
       [1, 1, 1, 1],
       [1, 0, 1, 0],
       [1, 1, 1, 1]]

>>> np.repeat(np.repeat(arr, 2, axis=1), 2, axis=0)

array([[1, 1, 0, 0],
       [1, 1, 0, 0],
       [1, 1, 1, 1],
       [1, 1, 1, 1]])

然后就相乘:

def tile_mask(a):
    tiled = np.tile(a, (2, 2))
    mask = np.repeat(
        np.repeat(a, 2, axis=1),
        2, axis=0
    )
    return tiled * mask

>>> tile_mask(arr)

array([[1, 0, 0, 0],
       [1, 1, 0, 0],
       [1, 0, 1, 0],
       [1, 1, 1, 1]])

除了递归,我不知道还有什么好的方法可以实现更高的幂:

def tile_mask(a, n=2):

    if n > 2:
        a = tile_mask(a, n-1)

    tiled = np.tile(a, (2, 2))
    mask = np.repeat(
        np.repeat(a, 2, axis=1),
        2, axis=0
    )
    return tiled * mask

>>> tile_mask(arr, 3)

array([[1, 0, 0, 0, 0, 0, 0, 0],
       [1, 1, 0, 0, 0, 0, 0, 0],
       [1, 0, 1, 0, 0, 0, 0, 0],
       [1, 1, 1, 1, 0, 0, 0, 0],
       [1, 0, 0, 0, 1, 0, 0, 0],
       [1, 1, 0, 0, 1, 1, 0, 0],
       [1, 0, 1, 0, 1, 0, 1, 0],
       [1, 1, 1, 1, 1, 1, 1, 1]])

相关问题