Comment fonctionne numpy.newaxis et quand l'utiliser?

187

Quand j'essaye

numpy.newaxis

le résultat me donne un cadre de tracé 2D avec l'axe des x de 0 à 1. Cependant, lorsque j'essaie d'utiliser numpy.newaxispour découper un vecteur,

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

Est-ce la même chose sauf que cela change un vecteur ligne en vecteur colonne?

En général, à quoi sert-il numpy.newaxiset dans quelles circonstances devons-nous l'utiliser?

Yue Harriet Huang
la source
1
except that it changes a row vector to a column vector? Le premier exemple n'est pas un vecteur de ligne. C'est un concept matlab. En python, c'est juste un vecteur à une dimension sans concept de ligne ou de colonne. Les vecteurs de ligne ou de colonne sont à 2 dimensions, comme le deuxième exemple
endolith

Réponses:

331

En termes simples, numpy.newaxisest utilisé pour augmenter la dimension du tableau existant d' une dimension supplémentaire , lorsqu'il est utilisé une fois . Donc,

  • Le tableau 1D deviendra un tableau 2D

  • Le tableau 2D deviendra un tableau 3D

  • Le tableau 3D deviendra un tableau 4D

  • La matrice 4D deviendra une matrice 5D

etc..

Voici une illustration visuelle qui représente la promotion d'un tableau 1D vers des tableaux 2D.

visualisation de canva newaxis


Scénario-1 : np.newaxispeut être utile lorsque vous souhaitez convertir explicitement un tableau 1D en vecteur de ligne ou en vecteur de colonne , comme illustré dans l'image ci-dessus.

Exemple:

# 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)

Scénario-2 : Lorsque nous voulons utiliser la diffusion numpy dans le cadre d'une opération, par exemple lors de l' ajout de certains tableaux.

Exemple:

Supposons que vous souhaitiez ajouter les deux tableaux suivants:

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

Si vous essayez de les ajouter comme ça, NumPy soulèvera les éléments suivants ValueError:

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

Dans cette situation, vous pouvez utiliser np.newaxispour augmenter la dimension de l'un des tableaux afin que NumPy puisse diffuser .

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

Maintenant, ajoutez:

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

Vous pouvez également ajouter un nouvel axe au tableau x2:

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

Maintenant, ajoutez:

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

Remarque : Observez que nous obtenons le même résultat dans les deux cas (mais l'un étant la transposition de l'autre).


Scénario-3 : Ceci est similaire au scénario-1. Mais vous pouvez en utiliser np.newaxisplusieurs pour promouvoir le tableau à des dimensions plus élevées. Une telle opération est parfois nécessaire pour les tableaux d'ordre supérieur ( c'est-à-dire les tenseurs ).

Exemple:

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)

Plus d'informations sur np.newaxis vs np.reshape

newaxis est également appelé pseudo-index qui permet l'ajout temporaire d'un axe dans un multiarray.

np.newaxisutilise l'opérateur de découpage pour recréer le tableau tout en np.reshaperemodelant le tableau à la disposition souhaitée (en supposant que les dimensions correspondent; et cela est indispensable pour que reshapecela se produise).

Exemple

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)

Dans l'exemple ci-dessus, nous avons inséré un axe temporaire entre les premier et deuxième axes de B(pour utiliser la diffusion). Un axe manquant est rempli ici np.newaxispour faire fonctionner l' opération de diffusion .


Conseil général : vous pouvez également utiliserNoneà la place denp.newaxis; Ce sont en fait les mêmes objets .

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

PS Voir également cette excellente réponse: newaxis vs remodeler pour ajouter des dimensions

kmario23
la source
3
Quel type d'opération est x1_new + x2? C'est bizarre pour moi parce que je pensais que deux matrices ne peuvent être ajoutées que si elles ont les mêmes dimensions (ou si l'une d'elles n'est en fait qu'un scalaire).
Stephen
2
@Stephen Comme je l'ai également noté dans la réponse, c'est à cause de NumPy Broadcasting.
kmario23
2
Ceci est une explication géniale
Valdrinium
2
@valdrinit heureux que cela vous soit utile :)
kmario23
1
@ kmario23 En effet l'attribution est cachée dans la toute dernière phrase de l'article, pas étonnant que je ne l'ai pas vue. Je considère qu'il s'agit d'un plagiat limite même avec cette attribution. Dans mon livre, la copie mot pour mot n'est acceptable que si c'est le même auteur qui publie sur différentes plateformes. J'attendais mieux de Medium.
Chiraz BenAbdelkader le
29

Qu'est-ce que c'est np.newaxis?

Le np.newaxisest juste un alias pour la constante Python None, ce qui signifie que partout où vous l'utilisez, np.newaxisvous pouvez également utiliser None:

>>> np.newaxis is None
True

C'est juste plus descriptif si vous lisez du code qui utilise np.newaxisau lieu de None.

Comment utiliser np.newaxis?

Le np.newaxisest généralement utilisé avec le tranchage. Cela indique que vous souhaitez ajouter une dimension supplémentaire au tableau. La position du np.newaxisreprésente où je veux ajouter des dimensions.

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

Dans le premier exemple, j'utilise tous les éléments de la première dimension et j'ajoute une seconde dimension:

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

Le deuxième exemple ajoute une dimension comme première dimension, puis utilise tous les éléments de la première dimension du tableau d'origine comme éléments de la deuxième dimension du tableau de résultat:

>>> 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)

De même, vous pouvez utiliser plusieurs np.newaxispour ajouter plusieurs dimensions:

>>> 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)

Existe-t-il des alternatives np.newaxis?

Il existe une autre fonctionnalité très similaire dans NumPy:, np.expand_dimsqui peut également être utilisée pour insérer une dimension:

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

Mais étant donné qu'il insère simplement 1s dans le, shapevous pouvez également reshapele tableau pour ajouter ces dimensions:

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

La plupart du temps, np.newaxisc'est le moyen le plus simple d'ajouter des dimensions, mais il est bon de connaître les alternatives.

Quand l'utiliser np.newaxis?

Dans plusieurs contextes, l'ajout de dimensions est utile:

  • Si les données doivent avoir un nombre spécifié de dimensions. Par exemple, si vous souhaitez utiliser matplotlib.pyplot.imshowpour afficher un tableau 1D.

  • Si vous souhaitez que NumPy diffuse des tableaux. En ajoutant une dimension , vous pouvez par exemple obtenir la différence entre tous les éléments d'un tableau: a - a[:, np.newaxis]. Cela fonctionne car les opérations NumPy sont diffusées en commençant par la dernière dimension 1 .

  • Pour ajouter une dimension nécessaire pour que NumPy puisse diffuser des tableaux. Cela fonctionne car chaque dimension de longueur 1 est simplement diffusée à la longueur de la dimension 1 correspondante de l'autre tableau.


1 Si vous voulez en savoir plus sur les règles de diffusion, la documentation NumPy sur ce sujet est très bonne. Il comprend également un exemple avec 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.]])
MSeifert
la source
Je ne vois pas la différence entre le 2ème et le 3ème cas d'utilisation; ils visent tous les deux à permettre à NumPy de diffuser un tableau dans le cadre d'une opération. Sinon, il serait utile d'ajouter un exemple pour le troisième cas d'utilisation afin de clarifier le point.
Chiraz BenAbdelkader
@ChirazBenAbdelkader Ouais, la distinction n'est pas vraiment si distincte. Je ne sais pas si je devrais supprimer le troisième point ou le fusionner avec le deuxième.
MSeifert le
9

Vous avez commencé avec une liste unidimensionnelle de nombres. Une fois que vous l'avez utilisé numpy.newaxis, vous l'avez transformé en une matrice à deux dimensions, composée de quatre lignes d'une colonne chacune.

Vous pouvez ensuite utiliser cette matrice pour la multiplication matricielle ou l'impliquer dans la construction d'une matrice 4 xn plus grande.

Kevin
la source
5

newaxisobjet dans le tuple de sélection sert à étendre les dimensions de la sélection résultante d' une dimension de longueur unitaire .

Il ne s'agit pas simplement de convertir une matrice de lignes en matrice de colonnes.

Prenons l'exemple ci-dessous:

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

Ajoutons maintenant une nouvelle dimension à nos données,

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

              [[4, 5, 6]],

              [[7, 8, 9]]])

Vous pouvez voir que l' newaxisajout de la dimension supplémentaire ici, x1 avait la dimension (3,3) et X1_new a la dimension (3,1,3).

Comment notre nouvelle dimension nous permet d'effectuer différentes opérations:

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

En ajoutant x1_new et x2, nous obtenons:

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]]])

Ainsi, il newaxisn'y a pas que la conversion de ligne en matrice de colonnes. Il augmente la dimension de la matrice, nous permettant ainsi de faire plus d'opérations sur elle.

dur hundiwala
la source
1
Ce n'est pas seulement une matrice, cela fonctionne avec n'importe quelle ndarrayterminologie NumPy.
kmario23