2015-09-24 17 views
7

Sto cercando di trovare un piccolo trucco per tagliare una riga/colonna da un array 2d e ottenere un array di (col_size x 1) o (1 x row_size).Numpy - slicing 2d row o column vector from array

C'è un modo più semplice di utilizzare numpy.reshape() dopo ogni taglio?

Cheers, Stephan

+0

È possibile fornire un esempio di input e output previsti, per favore? Vuoi ottenere un array 1D o un array 2D? –

+0

Sicuro! Diciamo che ho una matrice come 'np.ones ((2,40))'. Da questo array voglio tagliare un'intera riga sotto forma di 'np.array ((1,40))'. Il risultato dovrebbe essere un array 2d – neurotronix

+1

Utilizzare np.newaxis o None per inserire un nuovo asse –

risposta

11

È possibile tagliare e inserire un nuovo asse in una sola operazione. Ad esempio, ecco una matrice 2D:

>>> a = np.arange(1, 7).reshape(2, 3) 
>>> a 
array([[1, 2, 3], 
     [4, 5, 6]]) 

di affettare un singolo colonna (ritornando array di forma (2, 1)), fetta con None come terza dimensione:

>>> a[:, 1, None] 
array([[2], 
     [5]]) 

di affettare un singola fila (ritornando array di forma (1, 3)), affettare con None come seconda dimensione:

>>> a[0, None, :] 
array([[1, 2, 3]]) 
+0

Molte grazie! Giusto quello di cui avevo bisogno! Numpy è davvero grande, veloce e tutto, ma non molto intuitivo, almeno per me. – neurotronix

+1

Nessun problema! L'indicizzazione/rimodellamento richiede un po 'di tempo per avvolgere la tua mente (almeno lo ha fatto per me), ma ha senso dopo un po' di pratica. I [documenti] (http://docs.scipy.org/doc/numpy/reference/arrays.indexing.html) sono abbastanza buoni per spiegare cosa sta succedendo qui (la sezione * slicing di base *). –

+0

Stranamente non ho mai pensato di combinare l'indicizzazione con l'aggiunta "Nessuna". Immagino sia solo la forza dell'abitudine, usando 'Nessuno' per espandere le dimensioni di un array esistente. Ed è più veloce. – hpaulj

6

rendere l'indice una fetta, lista o un array

X[[0],:] 
    X[0:1,4] 

Ma non c'è niente di sbagliato con reshape a parte il fatto che essa richiede la digitazione. Non è lento. [None,:] è una bella mano corta per questo.

L'utilizzo di un indice di elenco può essere più breve, ma lo fa produrre una copia (una più o meno?) Ed è più lento

Per array di (100,100) intero:

In [487]: timeit x[[50],:] 
100000 loops, best of 3: 10.3 µs per loop # slowest 

In [488]: timeit x[50:51,:] 
100000 loops, best of 3: 2.24 µs per loop # slice indexing is fast 

In [489]: timeit x[50,:].reshape(1,-1) 
100000 loops, best of 3: 3.29 µs per loop # minimal time penalty 

In [490]: timeit x[50,:][None,:] 
100000 loops, best of 3: 3.55 µs per loop 

In [543]: timeit x[None,50,:]   # **best** 
1000000 loops, best of 3: 1.76 µs per loop 

Un test per la copia è quello di confrontare il puntatore del buffer di dati con l'originale.

In [492]: x.__array_interface__['data'] 
Out[492]: (175920456, False) 
In [493]: x[50,:].__array_interface__['data'] 
Out[493]: (175940456, False) 
In [494]: x[[50],:].__array_interface__['data'] 
Out[494]: (175871672, False) # different pointer 
In [495]: x[50:51,:].__array_interface__['data'] 
Out[495]: (175940456, False) 
In [496]: x[50,:][None,:].__array_interface__['data'] 
Out[496]: (175940456, False) 
+0

Grazie amico! – neurotronix

+0

Il problema è che sto implementando una rete neurale scalabile, scalabile in termini di dimensioni dei livelli. Con 'reshape' dovevo accedere spesso ad attributi di istanza diversi (ad esempio le dimensioni dei livelli). Infine, per farlo bene: quando uso 'a [0, None,:]' per tagliare una riga da 'array' a, verrà restituita una copia? – neurotronix

+1

'[0, None,:]' restituisce una vista. – hpaulj

1

Che ne dici di questo modo semplice e piacevole?

In [73]: arr = (np.arange(5, 25)).reshape(5, 4) 

In [74]: arr 
Out[74]: 
array([[ 5, 6, 7, 8], 
     [ 9, 10, 11, 12], 
     [13, 14, 15, 16], 
     [17, 18, 19, 20], 
     [21, 22, 23, 24]]) 

# extract column 1 as a column vector 
In [79]: col1 = arr[:, [0]] 
In [80]: col1.shape 
Out[80]: (5, 1) 

In [81]: col1 
Out[81]: 
array([[ 5], 
     [ 9], 
     [13], 
     [17], 
     [21]]) 


# extract row 1 as a row vector 
In [82]: row1 = arr[[0], :] 

In [83]: row1.shape 
Out[83]: (1, 4) 

In [84]: row1 
Out[84]: array([[5, 6, 7, 8]]) 
+0

Grazie per la risposta pulita e dettagliata! Ma non hai notato che la domanda ha più di due anni? Saluti :) – neurotronix

+0

@neurotronix L'ho appena capito. Ad ogni modo, per ragioni pedagogiche, il tempo non conta mai;) – kmario23

+0

Veramente, grazie per aver trovato il tempo di dare una risposta! – neurotronix