2015-07-14 14 views
6

Se io tagliare un array 2D con una serie di coordinateAffettare 3d serie NumPy torna strana forma

>>> test = np.reshape(np.arange(40),(5,8)) 
>>> coords = np.array((1,3,4)) 
>>> slice = test[:, coords] 

allora la mia fetta ha la forma che mi aspetterei

>>> slice.shape 
(5, 3) 

Ma se ripeto questo con una matrice 3d

>>> test = np.reshape(np.arange(80),(2,5,8)) 
>>> slice = test[0, :, coords] 

quindi la forma è ora

012.351.
>>> slice.shape 
(3, 5) 

C'è un motivo per cui questi sono diversi? Separare gli indici restituisce la forma che mi aspetterei

>>> slice = test[0][:][coords] 
>>> slice.shape 
(5, 3) 

Perché queste viste hanno forme diverse?

+0

Tra l'altro, non è legato alla tua domanda, 'slice()' è un pitone integrato, https://docs.python.org/2/library/functions.html#slice. Puoi usarlo possibilmente per nominare un oggetto fetta. – Scott

risposta

5
slice = test[0, :, coords] 

è semplice indicizzazione, in effetti dire "prendere l'elemento 0th della prima coordinata, tutta la seconda coordinata, e [1,3,4] della terza coordinata". O più precisamente, prendi le coordinate (0, qualunque cosa, 1) e rendi la nostra prima riga, (0, qualunque cosa, 2) e rendi la nostra seconda riga, e (0, qualunque cosa, 3) e rendila la nostra terza riga. Ci sono 5 whatevers, quindi si finisce con (3,5).

Il secondo esempio che ha dato è simile a questo:

slice = test[0][:][coords] 

In questo caso si sta guardando una (5,8) array, e poi con il 1 °, 3 ° e 4 ° elementi, che sono il 1a, 3a e 4a riga, quindi si ottiene una matrice (5,3).

Modifica per discutere caso 2D:

Nel caso in 2D, in cui:

>>> test = np.reshape(np.arange(40),(5,8)) 
>>> test 
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], 
     [24, 25, 26, 27, 28, 29, 30, 31], 
     [32, 33, 34, 35, 36, 37, 38, 39]]) 

il comportamento è simile.

Caso 1:

>>> test[:,[1,3,4]] 
array([[ 1, 3, 4], 
     [ 9, 11, 12], 
     [17, 19, 20], 
     [25, 27, 28], 
     [33, 35, 36]]) 

è semplicemente selezionando le colonne 1,3 e 4.

Caso 2:

>>> test[:][[1,3,4]] 
array([[ 8, 9, 10, 11, 12, 13, 14, 15], 
     [24, 25, 26, 27, 28, 29, 30, 31], 
     [32, 33, 34, 35, 36, 37, 38, 39]]) 

sta prendendo il 1 °, 3 ° e 4 ° elemento della array, che sono le righe.

+1

Questo ha senso per il caso 3d, ma perché il caso 2d è diverso? Perché non sta prendendo (qualunque cosa, 1) come prima riga? –

+1

Quindi, quando si inserisce lo 0 nel caso 3D, significa che si ha una combinazione di indicizzazione semplice e avanzata. L'indice avanzato diventa sempre il primo indice, che è ciò che lo scambia. –

+1

Nel caso 2D, non c'è alcuna miscela, quindi mantiene l'ordine esistente. –

4

http://docs.scipy.org/doc/numpy/reference/arrays.indexing.html#combining-advanced-and-basic-indexing

La documentazione parlano della complessità della combinazione di indicizzazione avanzati e di base.

test[0, :, coords] 

L'indicizzazione coords viene prima, con la [0,:] dopo, producendo il il (3,5).

Il modo più semplice per capire la situazione può essere quello di pensare in termini di forma del risultato.Ci sono due parti per l'operazione di indicizzazione, il sottospazio definito dall'indicizzazione di base (esclusi gli interi) e il sottospazio dalla parte di indicizzazione avanzata. [nel caso in cui]

Gli indici avanzati sono separati da una sezione, ellissi o newaxis. Ad esempio x [arr1,:, arr2]. .... le dimensioni risultanti dall'operazione di indicizzazione avanzata vengono prima nell'array dei risultati e successivamente le dimensioni del sottospazio.

Ricordo di aver discusso questo tipo di indicizzazione in una precedente domanda SO, ma ci sarebbe voluto qualche scavo per trovarlo.

https://stackoverflow.com/a/28353446/901925Why does the order of dimensions change with boolean indexing?

How does numpy order array slice indices?


Il [:] in test[0][:][coords] non fa nulla. test[0][:,coords] produce il risultato (5,3) desiderato.

In [145]: test[0,:,[1,2,3]] # (3,5) array 
Out[145]: 
array([[ 1, 9, 17, 25, 33], # test[0,:,1] 
     [ 2, 10, 18, 26, 34], 
     [ 3, 11, 19, 27, 35]]) 

In [146]: test[0][:,[1,2,3]] # same values but (5,3) 
Out[146]: 
array([[ 1, 2, 3], 
     [ 9, 10, 11], 
     [17, 18, 19], 
     [25, 26, 27], 
     [33, 34, 35]]) 

In [147]: test[0][:][[1,2,3]] # [:] does nothing; select 3 from 2nd axis 
Out[147]: 
array([[ 8, 9, 10, 11, 12, 13, 14, 15], 
     [16, 17, 18, 19, 20, 21, 22, 23], 
     [24, 25, 26, 27, 28, 29, 30, 31]]) 

In [148]: test[0][[1,2,3]] # same as test[0,[1,2,3],:] 
Out[148]: 
array([[ 8, 9, 10, 11, 12, 13, 14, 15], 
     [16, 17, 18, 19, 20, 21, 22, 23], 
     [24, 25, 26, 27, 28, 29, 30, 31]]) 
+0

Questa risposta ha molto senso, tranne che non spiega ancora perché il caso 2D si comporta come fa! – DilithiumMatrix