2015-03-11 15 views
6

Matlab ma dwie funkcje do konwersji indeksów macierzy do indeksów liniowych i na odwrót. (ind2sub i sub2ind)MATLAB odpowiednik ind2sub w Pythonie

Znalazłem odpowiednik dla R, ale czy istnieje odpowiednik w Pythonie?

+1

Sprawdź tutaj: https://github.com/jjakeman/pyheat/blob/master/utilities/math_utils.py – rayryeng

+3

Myślę, że będziesz miał więcej szczęścia, jeśli powiesz nam, co próbujesz zrobić. "Próbuję replikować tę funkcję z innego języka" nie jest często bardzo pomocny. Lepsze pytanie będzie sformatowane w sposób podobny do - - <(opcjonalnie) błędy, które twój kod rzuca) i opis o tym, co nie działa> - mgilson

+0

Możesz zajrzeć do numpy's ['unravel_index'] (http://docs.scipy.org/doc /numpy/reference/generated/numpy.unravel_index.html). – eigenchris

Odpowiedz

14

Wyszukiwarka Google doprowadzi mnie do tego linku: https://github.com/jjakeman/pyheat/blob/master/utilities/math_utils.py

Z tego co wiem, nie ma bezpośredniej realizacji tych funkcji w programie MATLAB.


Okazuje się, że nie mogę poprawnie odczytać dokumentacji. Jeśli chcesz korzystać z funkcji sub2ind, będziesz potrzebować funkcji ravel_multi_index. Deklaracja funkcji mówi, że potrzebujesz dwóch wejść. Pierwsze wejście to tablica 2D numpy, w której każdy wiersz jest położeniem określonego wymiaru. Na przykład, jeśli chcesz zastosować ind2sub na macierzy 2D, możesz określić tablicę 2D numpy, gdzie pierwszy wiersz składa się z wszystkich żądanych lokalizacji wierszy, a drugi wiersz zawiera wszystkie żądane lokalizacje kolumn. Drugie wejście to krotka, która określa rozmiar każdego wymiaru, więc dla tablicy 2D będzie to liczba wierszy i kolumn.

Aby wykonać ind2sub, należy użyć funkcji unravel_index. Pierwsze wejście to tablica indeksów liniowych, które chcesz przekształcić w lokalizacje każdego wymiaru w twojej tablicy. Drugie wejście jest krotką wymiarów jak poprzednio.

Zamierzam zostawić wpis u dołu dla potomności, na wypadek gdybyś chciał spróbować sam je wdrożyć.


Jednak można je z pewnością wdrożyć samodzielnie. Zakładam, że dlatego, że otagowałeś swój post z numerem numpy, będziesz potrzebował rozwiązania typu "lato". Pamiętaj, że w numpy uzyskujesz dostęp do elementów z kolumny , a więc dwie takie tablice, że jedna jest dla wiersza, a druga dla indeksów kolumnowych (z indeksowaniem 0), sub2ind dla macierzy 2D jest bardzo prosta:

def sub2ind(array_shape, rows, cols): 
    return rows*array_shape[1] + cols 

array_shape jest tablicą z dwóch elementów, gdy pierwszy element jest liczbą wierszy macierzy, a drugi element jest liczbą kolumn. Jeśli pamiętacie, można uzyskać dostęp do elementu w macierzy row-dur:

ind = r*cols + c 

(r,c) są wiersz i kolumna indeks chcesz, pod warunkiem, że to 0-indeksowane. Jechać w przeciwnym kierunku, to można wykorzystywać podział całkowitej oraz moduł:

def ind2sub(array_shape, ind): 
    rows = (ind.astype('int')/array_shape[1]) 
    cols = (ind.astype('int') % array_shape[1]) # or numpy.mod(ind.astype('int'), array_shape[1]) 
    return (rows, cols) 

Tutaj wyjście jest dwuelementowa krotka, w których pierwszy element jest rzędów szaf i drugi element lokalizacje kolumny. Aby podsumować ind2sub, aby uzyskać dostęp do żądanego wiersza, bierzesz indeks liniowy i wykonujesz podział liczb całkowitych z kolumnami. Aby uzyskać żądaną kolumnę, znajdź moduł lub pozostałą część. Przechodzenie do 3 wymiarów jest nieco bardziej skomplikowane. Zostawię Cię, aby rzucić okiem na link, o którym wspomniałem powyżej, aby uzyskać więcej informacji.

Oczywiście, nie umieściłem żadnej kontroli błędów w powyższych funkcjach, więc oczywiście używałbyś array_shape na swoją korzyść w tym przypadku. Lepszym sposobem na robienie tego, co chcesz byłoby coś jak:

def sub2ind(array_shape, rows, cols): 
    ind = rows*array_shape[1] + cols 
    ind[ind < 0] = -1 
    ind[ind >= array_shape[0]*array_shape[1]] = -1 
    return ind 

def ind2sub(array_shape, ind): 
    ind[ind < 0] = -1 
    ind[ind >= array_shape[0]*array_shape[1]] = -1 
    rows = (ind.astype('int')/array_shape[1]) 
    cols = ind % array_shape[1] 
    return (rows, cols) 

Zrobiłem podstawowe sprawdzanie błędów w celu zapewnienia, że ​​żadne wiersze lub kolumny dla sub2ind lub liniowych indeksy ind2sub są poza granicami. Ustawiłem te lokalizacje na -1, więc wiesz, że gdzieś się pogubiłeś.

Powodzenia!

3

Opierając się na odpowiedziach @rayryeng i @ theblackcat użytkownika, należy również pamiętać, że trzeba będzie użyć Fortran stylu indeksowanie i przypomnieć, że Python jest 0 indeksowane podczas MATLAB jest 1 indeksowanych .

Wymóg stylu Fortrana podniósł mnie trochę.

W Pythonie:

np.unravel_index(7, [1, 2, 3, 4], 'F') 
(0, 1, 0, 1) 

w Matlab/Octave

[a, b, c, d] = ind2sub([1, 2, 3, 4], 8) 
a = 1 
b = 2 
c = 1 
d = 2 
Powiązane problemy