2013-04-01 13 views
5

Ho cercato un modo (più efficiente che scrivere cicli di attraversare la matrice) per creare matrici di elementi dati in un ordine diagonale avvolto, ed estrarre i valori indietro in quest'ordine. Come esempio, in a = [2,3,4,5,6,7], vorrei essere in grado di generare la matriceWrapping/scartare un vettore lungo le diagonali della matrice

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

e anche essere in grado di ri-estratto a da tale matrice.

scipy.sparse.diags raggiunge qualcosa di molto simile a questo, ma come dice il nome è destinato per gli array sparsi. Esiste qualche tipo di funzionalità in numpy che fornisce questo o qualche forma di indicizzazione basata su diagonale? O forse un qualche tipo di trasformazione della matrice che renderebbe questo più fattibile?

+0

E 'intenzionale che la matrice è una matrice 1D? – askewchan

risposta

5

linea con l'approccio che Josh Adel propone, se si desidera mantenere i dati in ordine di diagonali, non righe, è solo bisogno di pasticciare un po 'in giro con il ritorno di np.triu_indices per costruire una propria routine generazione dell'indice :

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

E ora si può fare:

>>> 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 Nizza. Ho pensato che ci fosse qualcosa di semplice si potrebbe fare per riordinare le cose, ma non ha avuto il tempo di scavare in. Sono contento che hai postato la soluzione. – JoshAdel

3

Se siete disposti a ordinare a un po 'diverso si poteva fare qualcosa di simile:

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.]]) 

e quindi è possibile estrarre questi valori tramite:

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

Questo non è semplice, ma dovrebbe funzionare. Se noi ripartizione come NumPy trova indici diagonali possiamo ricostruire per ottenere ciò che si desidera.

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.]) 
Problemi correlati