【问题标题】:How to change the value of some m x m submatrices from an NxN matrix with numpy?如何使用 numpy 从 NxN 矩阵中更改一些 m x m 子矩阵的值?
【发布时间】:2021-12-06 06:45:13
【问题描述】:

我面临的一般问题可以翻译如下:

编码一个 NxN 矩阵,其中 x 或 y 值的 mxm 个子矩阵定期交替。

例如,假设我需要制作一个 6x6 矩阵,其中 0 或 1 的 2x2 子矩阵交替进行,结果应该是下面的矩阵:

0 0 1 1 0 0 
0 0 1 1 0 0
1 1 0 0 1 1
1 1 0 0 1 1
0 0 1 1 0 0
0 0 1 1 0 0

目前,我只设法得到这个:

0 0 1 0 0 0 
0 0 1 0 0 0 
1 1 0 0 0 0 
0 0 0 0 0 0
0 0 0 0 0 0 
0 0 0 0 0 0 

代码:

b = numpy.zeros((6, 6))
b[:2, 2:6:4] = 1
b[2:6:4, :2] = 1
print(b)

我设法找到了一个解决方案,但它有四个 for 循环,因此很难阅读并且需要一些时间。这个可能的答案的代码是:

c = np.array([])    
for k in range(3):
    for l in range (2):
        for i in range(3):
            for j in range (2):
            
                if (k+i)%2 == 0:
                    c = np.append(c, 0)
                else:
                    c = np.append(c, 1)
print("c = ", np.reshape(c, (6, 6)))

难道没有更好的方法可以在不使用循环或最多 1 或 2 个循环的情况下提供预期输出吗?

【问题讨论】:

    标签: python numpy matrix


    【解决方案1】:
    import numpy as np
    m = 8 
    n = 4
    
    c = np.zeros(shape=(m,m))    
    assert not m%n #m must be divisible by n
    for row_i in range(m):
      for col_i in range(m):
        if (row_i//n + col_i//n)%2:
          c[row_i][col_i] = 1
    
    print(c)
    
    [[0. 0. 0. 0. 1. 1. 1. 1.]
     [0. 0. 0. 0. 1. 1. 1. 1.]
     [0. 0. 0. 0. 1. 1. 1. 1.]
     [0. 0. 0. 0. 1. 1. 1. 1.]
     [1. 1. 1. 1. 0. 0. 0. 0.]
     [1. 1. 1. 1. 0. 0. 0. 0.]
     [1. 1. 1. 1. 0. 0. 0. 0.]
     [1. 1. 1. 1. 0. 0. 0. 0.]]
    

    【讨论】:

      【解决方案2】:

      我认为您在使用 python 数组切片方面走在了正确的轨道上。这是 2x2 子矩阵的示例(适用于任何偶数平方大小的矩阵 b)。

      # first block for submatrices starting at column and row index 0
      
      # 0::4 - every 4th column/row starting from column 0
      # so this results in 1 0 0 0 1 0 and so on
      b[0::4, 0::4] = 1
      
      # 1::4 - every 4th column starting from column 1
      # so this results in 0 1 0 0 0 1 and so on
      b[0::4, 1::4] = 1
      
      b[1::4, 0::4] = 1
      b[1::4, 1::4] = 1
      
      # second block for submatrices starting from column and row index 2 
      b[2::4, 2::4] = 1
      b[2::4, 3::4] = 1
      b[3::4, 2::4] = 1
      b[3::4, 3::4] = 1
      

      现在对于较大的子矩阵,您只需增加条目之间的距离。对于大小为n 的子矩阵,距离必须为2 * n,因为这是矩阵中1 重复的原因。然后每个块的大小为n。试着写一个程序。如果你不成功,我会进一步帮助。

      【讨论】:

        【解决方案3】:

        这是一个使用np.repeatnp.tile 的片段:

        import numpy as np
        
        def tiled_matrix(n, m):
          row = np.tile(np.repeat([1, 0], m), (n // m) // 2 + 1)[:n]
          row_block = np.tile(row, (m,1))
          two_rows_block = np.vstack((row_block, 1 - row_block))
          arr = np.tile(two_rows_block, ((n // m) // 2 + 1, 1))[:n]
          return arr
        
        print(tiled_matrix(10, 4))
        # [[1 1 1 1 0 0 0 0 1 1]
        #  [1 1 1 1 0 0 0 0 1 1]
        #  [1 1 1 1 0 0 0 0 1 1]
        #  [1 1 1 1 0 0 0 0 1 1]
        #  [0 0 0 0 1 1 1 1 0 0]
        #  [0 0 0 0 1 1 1 1 0 0]
        #  [0 0 0 0 1 1 1 1 0 0]
        #  [0 0 0 0 1 1 1 1 0 0]
        #  [1 1 1 1 0 0 0 0 1 1]
        #  [1 1 1 1 0 0 0 0 1 1]]
        

        这是np.meshgridxor 的另一个例子:

        def meshgrid_mod(n, m):
          ix = np.arange(n, dtype=np.uint8)
          xs, ys = np.meshgrid(ix, ix)
          arr = ((xs % (2*m)) < m) ^ ((ys % (2*m)) < m)
          return arr.astype(np.int)
        

        【讨论】:

          【解决方案4】:

          最简单的解决方案大概是使用skimage.util.view_as_blocks()

          import numpy as np
          import skimage.util
          
          a = np.zeros((6, 6))
          b = skimage.util.view_as_blocks(a, (2, 2))
          # b is a view of a, so changing values in b will also change values in a
          b[::2, ::2, ...] = 1
          b[1::2, 1::2, ...] = 1
          
          a
          # array([[1., 1., 0., 0., 1., 1.],
          #        [1., 1., 0., 0., 1., 1.],
          #        [0., 0., 1., 1., 0., 0.],
          #        [0., 0., 1., 1., 0., 0.],
          #        [1., 1., 0., 0., 1., 1.],
          #        [1., 1., 0., 0., 1., 1.]])
          

          【讨论】:

            猜你喜欢
            • 2017-03-07
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2012-05-18
            • 1970-01-01
            • 1970-01-01
            • 2015-08-02
            相关资源
            最近更新 更多