2015-01-10 48 views
5

我想更改2d矩陣的對角線元素。這些都是主對角線和非主對角線。Numpy:影響矩陣之前的對角元素1.10

numpy.diagonal() 在NumPy的1.10,它會返回一個讀/寫視圖,以書面形式向返回 陣列將改變原來的數組。

numpy.fill_diagonal()numpy.diag_indices() 只有主對角線元素的作品

這是我用例:我要重新創建下面的表格,這是一個矩陣考慮到我已經將所有的x,y,z作爲數組,所以使用對角線符號很平凡。

matrix

+0

'numpy.diag'呢? – talonmies

+1

我認爲'np.diag'調用'np.diagonal',它在Numpy 1.10之前呈現[難度](http://docs.scipy.org/doc/numpy/reference/generated/numpy.diagonal.html)當試圖將值寫入數組時。 –

+0

也許看看['scipy.sparse.diags'](http://docs.scipy.org/doc/scipy-0.14.0/reference/generated/scipy.sparse.diags.html)和['scipy 。疏。dia_matrix'](http://docs.scipy.org/doc/scipy-0.14.0/reference/generated/scipy.sparse.dia_matrix.htm)。 –

回答

4

您總是可以使用切片來分配值o r數組到對角線。

傳遞行索引列表和列索引列表可讓您直接(和高效地)訪問位置。例如:

>>> z = np.zeros((5,5)) 
>>> z[np.arange(5), np.arange(5)] = 1 # diagonal is 1 
>>> z[np.arange(4), np.arange(4) + 1] = 2 # first upper diagonal is 2 
>>> z[np.arange(4) + 1, np.arange(4)] = [11, 12, 13, 14] # first lower diagonal values 

改變零z的數組:

array([[ 1., 2., 0., 0., 0.], 
     [ 11., 1., 2., 0., 0.], 
     [ 0., 12., 1., 2., 0.], 
     [ 0., 0., 13., 1., 2.], 
     [ 0., 0., 0., 14., 1.]]) 

通常,對於一個k x k陣列稱爲z,可以設置i個上位對角線

z[np.arange(k-i), np.arange(k-i) + i] 

i th對角線較低

z[np.arange(k-i) + i, np.arange(k-i)] 

注意:如果你想避免調用np.arange幾次,你可以簡單地寫ix = np.arange(k)一次,然後切片該範圍需要:

np.arange(k-i) == ix[:-i] 
4

試試這個:

>>> A = np.zeros((6,6)) 
>>> i,j = np.indices(A.shape) 
>>> z = [1, 2, 3, 4, 5] 

現在你可以直觀地訪問任何對角線:

>>> A[i==j-1] = z 
>>> A 
array([[ 0., 1., 0., 0., 0., 0.], 
     [ 0., 0., 2., 0., 0., 0.], 
     [ 0., 0., 0., 3., 0., 0.], 
     [ 0., 0., 0., 0., 4., 0.], 
     [ 0., 0., 0., 0., 0., 5.], 
     [ 0., 0., 0., 0., 0., 0.]]) 

在您可以指定數組A[i==j]以同樣的方式,等

+0

沒有比較@ajcrs答案的性能,但爲了簡單起見,我喜歡這個。 – FooBar

+0

@FooBar這個方法在語法上比我的語法簡單得多:-)但是在性能方面,爲較大的矩陣構造一個掩碼(使用'i == j-1')效率不高。在1000x1000矩陣中,設置第一個較高對角線比直接指定索引要慢100倍左右。這是因爲你需要進行一百萬次'=='比較來構建布爾掩碼(更不用說在存儲器中有大的布爾矩陣)。當然,這個問題取決於你的用例。 –

1

這裏只是爲了好玩的另一種方法。您可以編寫自己的對角線函數來返回所需對角線的視圖。

import numpy as np 

def diag(a, k=0): 
    if k > 0: 
     a = a[:, k:] 
    elif k < 0: 
     a = a[-k:, :] 

    shape = (min(a.shape),) 
    strides = (sum(a.strides),) 
    return np.lib.stride_tricks.as_strided(a, shape, strides) 

a = np.arange(20).reshape((4, 5)) 
diag(a, 2)[:] = 88 
diag(a, -2)[:] = 99 
print(a) 
# [[ 0 1 88 3 4] 
# [ 5 6 7 88 9] 
# [99 11 12 13 88] 
# [15 99 17 18 19]] 
相關問題