2016-05-15 143 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)