2012-04-24 68 views
3

我想创建一个具有沿对角线向下运行的2D模式的稀疏矩阵。这可能是最简单的例子。如何在SciPy中创建对角线稀疏矩阵

说我的模式是:[1,0,2,0,1] ...

我想创建一个稀疏矩阵:

[[2,0,1,0,0,0,0...0], 
    [0,2,0,1,0,0,0...0], 
    [1,0,2,0,1,0,0...0], 
    [0,1,0,2,0,1,0...0], 
    [0,0,1,0,2,0,1...0], 
    [...]] 

的scipy.sparse.dia_matrix好像一个好的候选人,但是,我根本无法弄清楚如何从可用的文档中完成我想要的内容。谢谢你在前进

回答

6
N = 10 
diag = np.zeros(N) + 2 
udiag = np.zeros(N) + 1 
ldiag = np.zeros(N) + 1 
mat = scipy.sparse.dia_matrix(([diag, udiag, ldiag], [0, 2, -2]), shape=(N, N)) 
print mat.todense() 
[[ 2. 0. 1. 0. 0. 0. 0. 0. 0. 0.] 
[ 0. 2. 0. 1. 0. 0. 0. 0. 0. 0.] 
[ 1. 0. 2. 0. 1. 0. 0. 0. 0. 0.] 
[ 0. 1. 0. 2. 0. 1. 0. 0. 0. 0.] 
[ 0. 0. 1. 0. 2. 0. 1. 0. 0. 0.] 
[ 0. 0. 0. 1. 0. 2. 0. 1. 0. 0.] 
[ 0. 0. 0. 0. 1. 0. 2. 0. 1. 0.] 
[ 0. 0. 0. 0. 0. 1. 0. 2. 0. 1.] 
[ 0. 0. 0. 0. 0. 0. 1. 0. 2. 0.] 
[ 0. 0. 0. 0. 0. 0. 0. 1. 0. 2.]] 
+0

代替'np.zeros(N)+ 1'的,它可能是更清楚地做'np.ones(N)'。 :) – Dougal 2012-04-24 17:41:59

+2

:)它是np.zeros(N)+1的原因,因为作者可能会希望在那里有其他值(比如说100),然后代码仍然是相同的np.zeros (N)+100。但显然这是风格问题。 – 2012-04-24 17:57:17

+0

事实上,我确实需要一个和两个以外的值。谢谢!这个解决方案有多明显是很痛苦的,我只是不理解dia_matrix构造函数。 – user1354372 2012-04-25 15:07:50

0
In [27]: N = 5 

In [28]: diagonalvals = [7, 8, 9] 

In [29]: offsets = [-2, 0, 2] 

In [30]: diagonaldata = [[v for n in range(N)] for v in diagonalvals] 

In [31]: print diagonaldata 
[[7, 7, 7, 7, 7], [8, 8, 8, 8, 8], [9, 9, 9, 9, 9]] 

In [32]: A = scipy.sparse.dia_matrix((diagonaldata, offsets), shape=(N, N)) 

In [33]: print A 
    (2, 0) 7 
    (3, 1) 7 
    (4, 2) 7 
    (0, 0) 8 
    (1, 1) 8 
    (2, 2) 8 
    (3, 3) 8 
    (4, 4) 8 
    (0, 2) 9 
    (1, 3) 9 
    (2, 4) 9 
1

下面是创建这样一个列表的列表一个有趣的方法:

>>> n = 7 
>>> a = n*[0] + [1, 0, 2, 0, 1] + [0]*n 
>>> [a[-i+n+2:-i+2*n+2] for i in xrange(n)] 
[[2, 0, 1, 0, 0, 0, 0], 
[0, 2, 0, 1, 0, 0, 0], 
[1, 0, 2, 0, 1, 0, 0], 
[0, 1, 0, 2, 0, 1, 0], 
[0, 0, 1, 0, 2, 0, 1], 
[0, 0, 0, 1, 0, 2, 0], 
[0, 0, 0, 0, 1, 0, 2]]