2016-05-15 124 views
3

我想打一个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,我如何能够有效地填充对角线?

回答

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

你的答案是非常干净的,谢谢。 – CarMoreno

4

如果m表示1 s的连续数和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

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

然而,@约阿希姆 - 伊萨克森的答案是略微更加紧凑。

替代解决方案(基于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

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)