Come funziona numpy.newaxis e quando usarlo?


187

Quando ci provo

numpy.newaxis

il risultato mi dà un fotogramma 2D con asse x da 0 a 1. Tuttavia, quando provo a utilizzare numpy.newaxisper tagliare un vettore,

vector[0:4,]
[ 0.04965172  0.04979645  0.04994022  0.05008303]
vector[:, np.newaxis][0:4,]
[[ 0.04965172]
[ 0.04979645]
[ 0.04994022]
[ 0.05008303]]

È la stessa cosa, tranne che cambia un vettore di riga in un vettore di colonna?

In generale, a che cosa serve numpy.newaxise in quali circostanze dovremmo usarlo?


1
except that it changes a row vector to a column vector? Il primo esempio non è un vettore di riga. Questo è un concetto matlab. In Python è solo un vettore monodimensionale senza concetto di riga o colonna. I vettori di riga o colonna sono bidimensionali, come il secondo esempio
endolite

Risposte:


331

In poche parole, numpy.newaxisviene utilizzato per aumentare la dimensione dell'array esistente di un'altra dimensione , se utilizzato una volta . Così,

  • L' array 1D diventerà un array 2D

  • L' array 2D diventerà array 3D

  • L' array 3D diventerà un array 4D

  • L' array 4D diventerà un array 5D

e così via..

Ecco un'illustrazione visiva che descrive la promozione dell'array 1D in array 2D.

visualizzazione canva newaxis


Scenario 1 : np.newaxispotrebbe tornare utile quando si desidera convertire esplicitamente un array 1D in un vettore di riga o in un vettore di colonna , come illustrato nella figura sopra.

Esempio:

# 1D array
In [7]: arr = np.arange(4)
In [8]: arr.shape
Out[8]: (4,)

# make it as row vector by inserting an axis along first dimension
In [9]: row_vec = arr[np.newaxis, :]     # arr[None, :]
In [10]: row_vec.shape
Out[10]: (1, 4)

# make it as column vector by inserting an axis along second dimension
In [11]: col_vec = arr[:, np.newaxis]     # arr[:, None]
In [12]: col_vec.shape
Out[12]: (4, 1)

Scenario 2 : quando vogliamo utilizzare la trasmissione numpy come parte di alcune operazioni, ad esempio mentre facciamo l' aggiunta di alcune matrici.

Esempio:

Supponiamo che tu voglia aggiungere i seguenti due array:

 x1 = np.array([1, 2, 3, 4, 5])
 x2 = np.array([5, 4, 3])

Se provi ad aggiungerli in questo modo, NumPy genererà quanto segue ValueError:

ValueError: operands could not be broadcast together with shapes (5,) (3,)

In questa situazione, è possibile utilizzare np.newaxisper aumentare la dimensione di uno degli array in modo che NumPy possa trasmettere .

In [2]: x1_new = x1[:, np.newaxis]    # x1[:, None]
# now, the shape of x1_new is (5, 1)
# array([[1],
#        [2],
#        [3],
#        [4],
#        [5]])

Ora aggiungi:

In [3]: x1_new + x2
Out[3]:
array([[ 6,  5,  4],
       [ 7,  6,  5],
       [ 8,  7,  6],
       [ 9,  8,  7],
       [10,  9,  8]])

In alternativa, puoi anche aggiungere un nuovo asse all'array x2:

In [6]: x2_new = x2[:, np.newaxis]    # x2[:, None]
In [7]: x2_new     # shape is (3, 1)
Out[7]: 
array([[5],
       [4],
       [3]])

Ora aggiungi:

In [8]: x1 + x2_new
Out[8]: 
array([[ 6,  7,  8,  9, 10],
       [ 5,  6,  7,  8,  9],
       [ 4,  5,  6,  7,  8]])

Nota : osserva che otteniamo lo stesso risultato in entrambi i casi (ma uno è il recepimento dell'altro).


Scenario 3 : è simile allo scenario 1. Tuttavia, è possibile utilizzare np.newaxispiù di una volta per promuovere l'array a dimensioni superiori. Tale operazione è talvolta necessaria per array di ordine superiore ( cioè tensori ).

Esempio:

In [124]: arr = np.arange(5*5).reshape(5,5)

In [125]: arr.shape
Out[125]: (5, 5)

# promoting 2D array to a 5D array
In [126]: arr_5D = arr[np.newaxis, ..., np.newaxis, np.newaxis]    # arr[None, ..., None, None]

In [127]: arr_5D.shape
Out[127]: (1, 5, 5, 1, 1)

Ulteriori informazioni su np.newaxis vs np.reshape

newaxis viene anche chiamato come pseudo-indice che consente l'aggiunta temporanea di un asse in un multiarray.

np.newaxisutilizza l'operatore affettatura di ricreare la matrice mentre np.reshaperimodella la matrice al layout desiderato (supponendo che le dimensioni corrispondono, e questo è mosto per un reshapeaccada).

Esempio

In [13]: A = np.ones((3,4,5,6))
In [14]: B = np.ones((4,6))
In [15]: (A + B[:, np.newaxis, :]).shape     # B[:, None, :]
Out[15]: (3, 4, 5, 6)

Nell'esempio sopra, abbiamo inserito un asse temporaneo tra il primo e il secondo asse di B(per usare la trasmissione). Un asse mancante viene compilato qui usando np.newaxisper far funzionare l' operazione di trasmissione .


Suggerimento generale : puoi anche usareNoneal posto dinp.newaxis; Questi sono in effetti gli stessi oggetti .

In [13]: np.newaxis is None
Out[13]: True

PS Vedi anche questa grande risposta: newaxis vs reshape per aggiungere dimensioni


3
Che tipo di operazione è x1_new + x2? È strano per me perché ho pensato che due matrici possono essere aggiunte solo se hanno le stesse dimensioni (o se una di esse è in realtà solo uno scalare).
Stephen,

2
@Stephen Come ho notato anche nella risposta, è a causa di NumPy Broadcasting.
kmario23,

2
Questa è una spiegazione fantastica
Valdrinium,

2
@valdrinit felice che ti sia utile :)
kmario23

1
@ kmario23 In effetti l'attribuzione è nascosta nell'ultima frase dell'articolo, non c'è da stupirsi che non l'ho visto. Lo considero un plagio limite anche con questa attribuzione. Nel mio libro, la copia parola per parola è accettabile solo se è lo stesso autore che pubblica su piattaforme diverse. Mi aspettavo di meglio da Medium.
Chiraz BenAbdelkader

29

Che cosa è np.newaxis?

Il np.newaxisè solo un alias per la costante di Python None, il che significa che ovunque si utilizza np.newaxissi potrebbe anche usare None:

>>> np.newaxis is None
True

È solo più descrittivo se leggi il codice che utilizza np.newaxisinvece di None.

Come usare np.newaxis?

Il np.newaxisviene solitamente utilizzata con affettare. Indica che si desidera aggiungere una dimensione aggiuntiva all'array. La posizione del np.newaxisrappresenta dove voglio aggiungere dimensioni.

>>> import numpy as np
>>> a = np.arange(10)
>>> a
array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
>>> a.shape
(10,)

Nel primo esempio uso tutti gli elementi della prima dimensione e aggiungo una seconda dimensione:

>>> a[:, np.newaxis]
array([[0],
       [1],
       [2],
       [3],
       [4],
       [5],
       [6],
       [7],
       [8],
       [9]])
>>> a[:, np.newaxis].shape
(10, 1)

Il secondo esempio aggiunge una dimensione come prima dimensione e quindi utilizza tutti gli elementi della prima dimensione dell'array originale come elementi nella seconda dimensione dell'array dei risultati:

>>> a[np.newaxis, :]  # The output has 2 [] pairs!
array([[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]])
>>> a[np.newaxis, :].shape
(1, 10)

Allo stesso modo è possibile utilizzare più np.newaxisper aggiungere più dimensioni:

>>> a[np.newaxis, :, np.newaxis]  # note the 3 [] pairs in the output
array([[[0],
        [1],
        [2],
        [3],
        [4],
        [5],
        [6],
        [7],
        [8],
        [9]]])
>>> a[np.newaxis, :, np.newaxis].shape
(1, 10, 1)

Ci sono alternative a np.newaxis?

C'è un'altra funzionalità molto simile in NumPy:, np.expand_dimsche può anche essere usata per inserire una dimensione:

>>> np.expand_dims(a, 1)  # like a[:, np.newaxis]
>>> np.expand_dims(a, 0)  # like a[np.newaxis, :]

Ma dato che inserisce solo 1s nell'array shapepotresti anche reshapeaggiungere l'array per aggiungere queste dimensioni:

>>> a.reshape(a.shape + (1,))  # like a[:, np.newaxis]
>>> a.reshape((1,) + a.shape)  # like a[np.newaxis, :]

Il più delle volte np.newaxisè il modo più semplice per aggiungere dimensioni, ma è bene conoscere le alternative.

Quando usare np.newaxis?

In diversi contesti è utile aggiungere dimensioni:

  • Se i dati devono avere un numero specificato di dimensioni. Ad esempio, se si desidera utilizzare matplotlib.pyplot.imshowper visualizzare un array 1D.

  • Se si desidera che NumPy trasmetta array. Con l'aggiunta di una dimensione si potrebbe ad esempio ottenere la differenza tra tutti gli elementi di un array: a - a[:, np.newaxis]. Questo funziona perché le operazioni di NumPy vengono trasmesse a partire dall'ultima dimensione 1 .

  • Aggiungere una dimensione necessaria in modo che NumPy possa trasmettere array. Questo funziona perché ogni dimensione di lunghezza 1 viene semplicemente trasmessa alla lunghezza della 1 dimensione corrispondente dell'altro array.


1 Se vuoi saperne di più sulle regole di trasmissione, la documentazione di NumPy sull'argomento è molto buona. Include anche un esempio con np.newaxis:

>>> a = np.array([0.0, 10.0, 20.0, 30.0])
>>> b = np.array([1.0, 2.0, 3.0])
>>> a[:, np.newaxis] + b
array([[  1.,   2.,   3.],
       [ 11.,  12.,  13.],
       [ 21.,  22.,  23.],
       [ 31.,  32.,  33.]])

Non vedo la differenza tra il 2o e il 3o caso d'uso; si tratta entrambi di consentire a NumPy di ​​trasmettere un array come parte di alcune operazioni. In caso contrario, sarebbe utile aggiungere un esempio per il 3o caso d'uso al fine di chiarire il punto.
Chiraz BenAbdelkader,

@ChirazBenAbdelkader Sì, la distinzione non è poi così distinta. Non sono sicuro se dovrei rimuovere il terzo punto o unirlo nel secondo.
MSeifert,

9

Hai iniziato con un elenco unidimensionale di numeri. Una volta usato numpy.newaxis, lo hai trasformato in una matrice bidimensionale, composta da quattro file di una colonna ciascuna.

È quindi possibile utilizzare quella matrice per la moltiplicazione della matrice o coinvolgerla nella costruzione di una matrice 4 xn più grande.


5

newaxisL'oggetto nella tupla di selezione serve per espandere le dimensioni della selezione risultante di una dimensione di lunghezza unitaria .

Non è solo la conversione della matrice di righe in matrice di colonne.

Considera l'esempio seguente:

In [1]:x1 = np.arange(1,10).reshape(3,3)
       print(x1)
Out[1]: array([[1, 2, 3],
               [4, 5, 6],
               [7, 8, 9]])

Ora consente di aggiungere una nuova dimensione ai nostri dati,

In [2]:x1_new = x1[:,np.newaxis]
       print(x1_new)
Out[2]:array([[[1, 2, 3]],

              [[4, 5, 6]],

              [[7, 8, 9]]])

Puoi vedere che qui è stata newaxisaggiunta la dimensione aggiuntiva, x1 aveva dimensione (3,3) e X1_new ha dimensione (3,1,3).

In che modo la nostra nuova dimensione ci consente di svolgere diverse operazioni:

In [3]:x2 = np.arange(11,20).reshape(3,3)
       print(x2)
Out[3]:array([[11, 12, 13],
              [14, 15, 16],
              [17, 18, 19]]) 

Aggiungendo x1_new e x2, otteniamo:

In [4]:x1_new+x2
Out[4]:array([[[12, 14, 16],
               [15, 17, 19],
               [18, 20, 22]],

              [[15, 17, 19],
               [18, 20, 22],
               [21, 23, 25]],

              [[18, 20, 22],
               [21, 23, 25],
               [24, 26, 28]]])

Pertanto, newaxisnon è solo la conversione della matrice da riga a colonna. Aumenta la dimensione della matrice, permettendoci così di fare più operazioni su di essa.


1
Non è solo una matrice, funziona con qualsiasi ndarraynella terminologia di NumPy.
kmario23,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.