2013-04-01 44 views
5

我一直在尋找一種方法(更有效的方法是隻編寫循環來遍歷矩陣),從包含對角線順序的元素中創建矩陣,並將值提取回這個命令。作爲一個例子,給出a = [2,3,4,5,6,7],我想是能夠產生陣列沿着陣列對角線包裝/解開一個矢量

[ 0, 2, 5, 7, 
    0, 0, 3, 6, 
    0, 0, 0, 4, 
    0, 0, 0, 0] 

,也能夠從該陣列重新抽取a

scipy.sparse.diags實現了很多像這樣的東西,但正如其名稱所暗示的是用於稀疏數組。在numpy中是否有任何類型的功能提供這種功能,或者某種形式的基於對角線的索引?或者,也許某種類型的數組轉換會使這更加可行?

+0

是不是故意的,你的數組是一維數組? – askewchan

回答

5

與約什 - 阿德爾建議,如果你想保留通過對角線排列數據的方法是一致的,而不是行,你只需要爛攤子一點與周圍的回報np.triu_indices建立自己的指數生成過程:

def my_triu_indices(n, k=0): 
    rows, cols = np.triu_indices(n, k) 
    rows = cols - rows - k 
    return rows, cols 

現在你可以這樣做:

>>> a = np.array([2,3,4,5,6,7]) 
>>> b = np.zeros((4, 4), dtype=a.dtype) 
>>> b[my_triu_indices(4, 1)] = a 
>>> b 
array([[0, 2, 5, 7], 
     [0, 0, 3, 6], 
     [0, 0, 0, 4], 
     [0, 0, 0, 0]]) 
>>> b[my_triu_indices(4, 1)] 
array([2, 3, 4, 5, 6, 7]) 
+0

+1不錯。我覺得有一些簡單的辦法可以對事物進行重新排序,但沒有時間去挖掘。很高興你發佈瞭解決方案。 – JoshAdel

3

如果你願意訂購a有點不同,你可以這樣做:

import numpy as np 
a = [2,5,7,3,6,4] 
b = np.zeros((4,4)) 
b[np.triu_indices(4,1)] = a 
In [11]: b 
Out[11]: 
array([[ 0., 2., 5., 7.], 
     [ 0., 0., 3., 6.], 
     [ 0., 0., 0., 4.], 
     [ 0., 0., 0., 0.]]) 

,然後就可以通過提取這些值了:

In [23]: b[np.triu_indices(4,1)] 
Out[23]: array([ 2., 5., 7., 3., 6., 4.]) 
2

這並不簡單,但應該管用。如果我們分解numpy如何找到對角線索引,我們可以重建它以獲得你想要的。

def get_diag_indices(s,k): 
    n = s 
    if (k >= 0): 
     i = np.arange(0,n-k) 
     fi = i+k+i*n 
    else: 
     i = np.arange(0,n+k) 
     fi = i+(i-k)*n 
    return fi 

indices=np.hstack(([get_diag_indices(4,1+x) for x in range(3)])) 
a=np.array([2, 3, 4, 5, 6, 7]) 
out=np.zeros((4,4)) 

>>> out.flat[indices]=a 
>>> out 
array([[ 0., 2., 5., 7.], 
     [ 0., 0., 3., 6.], 
     [ 0., 0., 0., 4.], 
     [ 0., 0., 0., 0.]]) 

>>> out.flat[indices] 
array([ 2., 3., 4., 5., 6., 7.])