Numpy中的特殊矩阵

时间:2016-05-15 18:17:53

标签: python numpy

我想创建一个看起来像这样的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,我怎样才能有效地填充对角线?

4 个答案:

答案 0 :(得分:9)

一种方法是简单地水平拉伸身份数组;

> 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]])

答案 1 :(得分:4)

如果m表示行中1的数量和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]])

答案 2 :(得分:2)

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

答案 3 :(得分:1)

嗯,只是为了完成具有明显替代方案的系列,还有block_diag onal:

 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)