【问题标题】:Special Matrix in NumpyNumpy中的特殊矩阵
【发布时间】:2016-05-15 18:17:52
【问题描述】:

我想创建一个如下所示的 numpy 数组:

m = [1, 1, 1, 0, 0, 0, 0, 0, 0
     0, 0, 0, 1, 1, 1, 0, 0, 0 
     0, 0, 0, 0, 0, 0, 1, 1, 1]

我已经看到这个答案 Make special diagonal matrix in Numpy 并且我有这个:

a = np.zeros(3,9)
a[0, 0] = 1
a[0, 1] = 1
a[0, 2] = 1
a[1, 3] = 1
a[1, 4] = 1
a[1, 5] = 1
a[2, 6] = 1
a[2, 7] = 1
a[2, 8] = 1

但我想使用'for' cicle,如何有效地填充对角线?

【问题讨论】:

    标签: python numpy


    【解决方案1】:

    一种方法是简单地水平拉伸一个标识数组;

    > np.repeat(np.identity(3, dtype=int), 3, axis=1)
    
    array([[1, 1, 1, 0, 0, 0, 0, 0, 0],
           [0, 0, 0, 1, 1, 1, 0, 0, 0],
           [0, 0, 0, 0, 0, 0, 1, 1, 1]])
    

    【讨论】:

      【解决方案2】:

      如果m 表示1s 的行数,n 表示行数,可以列出两种方法来解决它。

      使用np.kron 这很简单,就像这样 -

      def kron_based(m,n):
          return np.kron(np.eye(n,dtype=int), np.ones(m,dtype=int))
      

      使用零初始化和填充将是 -

      def initialization_based(m,n):
          A = np.zeros((n,n*m),dtype=int)
          A.reshape(n,n,m)[np.eye(n,dtype=bool)] = 1
          return A
      

      示例运行 -

      In [54]: m = 4 # Number of 1s in a row. Note that this is 3 for your case
          ...: n = 3 # Number of rows
          ...: 
      
      In [55]: initialization_based(m,n)
      Out[55]: 
      array([[1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0],
             [0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0],
             [0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1]])
      
      In [56]: kron_based(m,n)
      Out[56]: 
      array([[1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0],
             [0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0],
             [0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1]])
      

      【讨论】:

        【解决方案3】:

        np.tile(np.eye(3, dtype=int)[:,:, np.newaxis], (1,1,3)).reshape(3,-1)

        不过,@joachim-isaksson 的回答稍微紧凑一些。

        替代方案(基于LA矩阵乘法dot函数):

        np.dot(np.eye(3, dtype=int)[:,:, np.newaxis], np.array([[1,1,1],])).reshape(3,-1)

        更新:toeplitz() 可用于构建特殊矩阵:

        from scipy.linalg import toeplitz (np.abs((toeplitz(np.arange(12),-np.arange(12)))[1:8:3,:9])<2)*1

        【讨论】:

          【解决方案4】:

          好吧,只是为了用明显的替代品完成这个系列,还有block_diagonal:

           import numpy as np
           import scipy as sp
          
           sp.linalg.block_diag(*[np.ones((1,3),dtype=int)]*5)
          

          或者如果你喜欢那种东西

           sp.linalg.block_diag(*[[1]*3]*5)
          

          【讨论】:

            猜你喜欢
            • 2016-05-22
            • 2013-08-04
            • 2014-11-08
            • 1970-01-01
            • 2014-07-13
            • 2022-11-21
            • 2020-12-24
            • 1970-01-01
            • 2013-11-24
            相关资源
            最近更新 更多