2013-04-01 12 views
5

Szukałem sposobu (bardziej wydajnego niż pisanie pętli do przechodzenia przez macierz), aby utworzyć macierze z elementów podanych w zapakowanej kolejności ukośnej, i wyodrębnić wartości z powrotem w ten porzadek. Na przykład, biorąc pod uwagę a = [2,3,4,5,6,7] chciałbym móc wygenerowania ArrayZawijanie/rozpakowanie wektora wzdłuż przekątnych tablicy

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

a także można ponownie ekstrahować a z tablicy.

scipy.sparse.diags osiąga coś takiego, ale jak sama nazwa wskazuje, jest przeznaczona do rzadkich tablic. Czy istnieje jakaś funkcjonalność w numpy, która zapewnia to, lub jakąś formę opartego na przekątowaniu indeksowania? A może jakiś rodzaj transformacji tablicowej, który uczyniłby to bardziej wykonalnym?

+0

Czy to zamierzone, czy tablica jest tablicą 1d? – askewchan

Odpowiedz

5

zgodne z podejściem, że Josh Adel proponuje, jeśli chcesz zachować swoje dane zlecenie przekątnych, a nie wiersze, wystarczy bałagan trochę dookoła ze zwrotem np.triu_indices zbudować własny rutynowych generacji indeks :

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

I teraz można zrobić:

>>> 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 Nicea. Doszedłem do wniosku, że jest coś, co można zrobić, by zmienić porządek, ale nie miał czasu, żeby się w to wkopać. Cieszę się, że napisałeś rozwiązanie. – JoshAdel

3

Jeśli jesteś gotów na zamówienie a nieco inaczej mógłby zrobić coś takiego:

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

a następnie można wyodrębnić te wartości za pośrednictwem:

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

To nie jest proste, ale powinno działać. Jeśli rozwiążemy jak numpy znajdzie indeksy diagonalne, możemy je odbudować, aby uzyskać to, czego chcesz.

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.]) 
Powiązane problemy