2013-03-05 12 views
13

Matlab oferuje funkcję sub2ind, która "zwraca równoważniki indeksu liniowego do indeksu dolnego wiersza i kolumny ... dla macierzy ...".Jak uzyskać liniowy indeks dla tablicy numpy (sub2ind)

Potrzebuję tej funkcji sub2ind lub czegoś podobnego, ale nie znalazłem żadnej podobnej funkcji Python lub Numpy. Jak mogę uzyskać tę funkcjonalność?

To jest przykład z matlab documentation samej stronie (jak wyżej):

Example 1 

This example converts the subscripts (2, 1, 2) for three-dimensional array A 
to a single linear index. Start by creating a 3-by-4-by-2 array A: 

rng(0,'twister'); % Initialize random number generator. 
A = rand(3, 4, 2) 

A(:,:,1) = 
    0.8147 0.9134 0.2785 0.9649 
    0.9058 0.6324 0.5469 0.1576 
    0.1270 0.0975 0.9575 0.9706 
A(:,:,2) = 
    0.9572 0.1419 0.7922 0.0357 
    0.4854 0.4218 0.9595 0.8491 
    0.8003 0.9157 0.6557 0.9340 

Find the linear index corresponding to (2, 1, 2): 

linearInd = sub2ind(size(A), 2, 1, 2) 
linearInd = 
    14 
Make sure that these agree: 

A(2, 1, 2)   A(14) 
ans =     and = 
    0.4854    0.4854 

Odpowiedz

20

myślę chcesz użyć np.ravel_multi_index. Z indeksowaniem zerowej opartej numpy, a także biorąc pod uwagę, że macierze MATLAB są Fortran styl, odpowiednik do Matlab przykładzie:

>>> np.ravel_multi_index((1, 0, 1), dims=(3, 4, 2), order='F') 
13 

Wystarczy więc zrozumieć, co się dzieje, można uzyskać ten sam wynik z iloczyn ilościowy twoich indeksów i kroków tablicy:

>>> a = np.random.rand(3, 4, 2) 
>>> np.dot((1, 0, 1), a.strides)/a.itemsize 
9.0 
>>> np.ravel_multi_index((1, 0, 1), dims=(3, 4, 2), order='C') 
9 
>>> a[1, 0, 1] 
0.26735433071594039 
>>> a.ravel()[9] 
0.26735433071594039 
+3

To trochę mylące. Dzięki temu wygląda na to, że musisz znać układ pamięci tablicy, aby użyć płaskiego indeksowania, co nie jest prawdą. Metoda kroków będzie działać tylko na macierzach C-Contiguous, ale zawsze będzie to prawda: 'A [idx] == A.flat [flat_idx] == A.ravel() [flat_idx]' if 'flat_idx = np.ravel_multi_index (idx, A.shape) '. Warto zauważyć, że 'flat_idx' są obliczane inaczej w matlab i numpy. –

1

To jest jak I rozwiązać problem dla mnie, przepisana być podobny do przykładu podanego powyżej.

Główną ideą jest utworzenie tablicy pomocniczej z indeksami za pomocą arange i reshape.

In [1]: import numpy as np 

In [2]: A = np.random.rand(3,4,2) 

In [3]: A 
Out[3]: 
array([[[ 0.79341698, 0.55131024], 
     [ 0.29294586, 0.22209375], 
     [ 0.11514749, 0.15150307], 
     [ 0.71399288, 0.11229617]], 

     [[ 0.74384776, 0.96777714], 
     [ 0.1122338 , 0.23915265], 
     [ 0.28324322, 0.7536933 ], 
     [ 0.29788946, 0.54770654]], 

     [[ 0.13496253, 0.24959013], 
     [ 0.36350264, 0.00438861], 
     [ 0.77178808, 0.66411135], 
     [ 0.26756112, 0.54042292]]]) 

In [4]: helper = np.arange(3*4*2) 

In [5]: helper 
Out[5]: 
array([ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 
     17, 18, 19, 20, 21, 22, 23]) 

In [6]: helper = helper.reshape([3,4,2]) 

In [7]: helper 
Out[7]: 
array([[[ 0, 1], 
     [ 2, 3], 
     [ 4, 5], 
     [ 6, 7]], 

     [[ 8, 9], 
     [10, 11], 
     [12, 13], 
     [14, 15]], 

     [[16, 17], 
     [18, 19], 
     [20, 21], 
     [22, 23]]]) 

In [8]: linear_index = helper[1,0,1] 

In [9]: linear_index 
Out[9]: 9 

zauważyć, że:

  • wiersze i kolumny są przełączane w NumPy odnośnie do Matlab.
  • Matlab zaczyna indeksy 1, Python i Numpy z 0.
Powiązane problemy