
Vous pouvez ajouter de nouvelles dimensions à un tableau NumPy ndarray (= décompresser un tableau NumPy) avec np.newaxis, np.expand_dims() et np.reshape() (ou la méthode reshape() de ndarray).
np.expand_dims() est similaire à torch.unsqueeze() dans PyTorch. Notez que np.unsqueeze() n’est pas fourni.
Cet article décrit le contenu suivant.
- Comment utiliser np.newaxis
- np.newaxis est Aucun
- Ajouter de nouvelles dimensions avec np.newaxis
- Contrôler la diffusion avec np.newaxis
- Ajouter une nouvelle dimension avec np.expand_dims()
- np.reshape()
Vous pouvez utiliser la méthode np.reshape() ou reshape() de ndarray pour non seulement ajouter des dimensions, mais également modifier n’importe quelle forme.
Vous pouvez utiliser np.squeeze() pour supprimer les dimensions de taille 1.
Comment utiliser np.newaxis
np.newaxis est Aucun
np.newaxis est un alias pour None.
import numpy as np
print(np.newaxis is None)
# True
Il est juste donné un alias pour le rendre plus facile à comprendre. Si vous remplacez np.newaxis dans l’exemple de code ci-dessous par None, cela fonctionne de la même manière.
Ajouter de nouvelles dimensions avec np.newaxis
L’utilisation de np.newaxis à l’intérieur de [] ajoute une nouvelle dimension de taille 1 à cette position.
a = np.arange(6).reshape(2, 3)
print(a)
# [[0 1 2]
# [3 4 5]]
print(a.shape)
# (2, 3)
print(a[:, :, np.newaxis])
# [[[0]
# [1]
# [2]]
#
# [[3]
# [4]
# [5]]]
print(a[:, :, np.newaxis].shape)
# (2, 3, 1)
print(a[:, np.newaxis, :])
# [[[0 1 2]]
#
# [[3 4 5]]]
print(a[:, np.newaxis, :].shape)
# (2, 1, 3)
print(a[np.newaxis, :, :])
# [[[0 1 2]
# [3 4 5]]]
print(a[np.newaxis, :, :].shape)
# (1, 2, 3)
Le : de fin dans [] peut être omis.
print(a[:, np.newaxis])
# [[[0 1 2]]
#
# [[3 4 5]]]
print(a[:, np.newaxis].shape)
# (2, 1, 3)
print(a[np.newaxis])
# [[[0 1 2]
# [3 4 5]]]
print(a[np.newaxis].shape)
# (1, 2, 3)
Consécutif : peut être remplacé par …. Si vous souhaitez ajouter une nouvelle dimension à la dernière dimension de ndarray, qui a de nombreuses dimensions, il est plus simple d’utiliser ….
print(a[..., np.newaxis])
# [[[0]
# [1]
# [2]]
#
# [[3]
# [4]
# [5]]]
print(a[..., np.newaxis].shape)
# (2, 3, 1)
Vous pouvez utiliser plusieurs np.newaxis à la fois. Plusieurs dimensions sont ajoutées.
print(a[np.newaxis, :, np.newaxis, :, np.newaxis])
# [[[[[0]
# [1]
# [2]]]
#
#
# [[[3]
# [4]
# [5]]]]]
print(a[np.newaxis, :, np.newaxis, :, np.newaxis].shape)
# (1, 2, 1, 3, 1)
L’ajout d’une dimension par np.newaxis renvoie une vue de l’objet d’origine. Étant donné que l’objet d’origine et l’objet de vue partagent la mémoire, la modification d’un élément modifie l’autre élément.
a_newaxis = a[:, :, np.newaxis]
print(np.shares_memory(a, a_newaxis))
# True
Contrôler la diffusion avec np.newaxis
Dans le fonctionnement de deux tableaux NumPy, ils sont automatiquement remodelés dans la même forme par diffusion.
a = np.zeros(27, dtype=np.int).reshape(3, 3, 3)
print(a)
# [[[0 0 0]
# [0 0 0]
# [0 0 0]]
#
# [[0 0 0]
# [0 0 0]
# [0 0 0]]
#
# [[0 0 0]
# [0 0 0]
# [0 0 0]]]
print(a.shape)
# (3, 3, 3)
b = np.arange(9).reshape(3, 3)
print(b)
# [[0 1 2]
# [3 4 5]
# [6 7 8]]
print(b.shape)
# (3, 3)
print(a + b)
# [[[0 1 2]
# [3 4 5]
# [6 7 8]]
#
# [[0 1 2]
# [3 4 5]
# [6 7 8]]
#
# [[0 1 2]
# [3 4 5]
# [6 7 8]]]
En diffusion, une nouvelle dimension est ajoutée au début du tableau avec un plus petit nombre de dimensions.
Si vous ajoutez une nouvelle dimension au début avec np.newaxis, le résultat sera le même que s’il était automatiquement converti par diffusion.
print(b[np.newaxis, :, :].shape)
# (1, 3, 3)
print(a + b[np.newaxis, :, :])
# [[[0 1 2]
# [3 4 5]
# [6 7 8]]
#
# [[0 1 2]
# [3 4 5]
# [6 7 8]]
#
# [[0 1 2]
# [3 4 5]
# [6 7 8]]]
Changer la position à ajouter donnera des résultats différents.
print(b[:, np.newaxis, :].shape)
# (3, 1, 3)
print(a + b[:, np.newaxis, :])
# [[[0 1 2]
# [0 1 2]
# [0 1 2]]
#
# [[3 4 5]
# [3 4 5]
# [3 4 5]]
#
# [[6 7 8]
# [6 7 8]
# [6 7 8]]]
print(b[:, :, np.newaxis].shape)
# (3, 3, 1)
print(a + b[:, :, np.newaxis])
# [[[0 0 0]
# [1 1 1]
# [2 2 2]]
#
# [[3 3 3]
# [4 4 4]
# [5 5 5]]
#
# [[6 6 6]
# [7 7 7]
# [8 8 8]]]
Par exemple, si vous souhaitez ajouter ou soustraire des tableaux d’image couleur (forme :(height, width, color)) and monochromatic image (shape:
(height, width)), it is impossible to broadcast the image as it is, but adding a new dimension at the end of the monochromatic image works well.
Ajouter une nouvelle dimension avec np.expand_dims()
Vous pouvez également ajouter une nouvelle dimension à un tableau NumPy avec np.expand_dims().
Spécifiez le ndarray d’origine dans le premier argument a et la position pour ajouter la dimension dans l’axe du deuxième argument.
a = np.arange(6).reshape(2, 3)
print(a)
# [[0 1 2]
# [3 4 5]]
print(np.expand_dims(a, 0))
# [[[0 1 2]
# [3 4 5]]]
print(np.expand_dims(a, 0).shape)
# (1, 2, 3)
Vous pouvez insérer une nouvelle cote à n’importe quelle position comme suit :
print(np.expand_dims(a, 0).shape)
# (1, 2, 3)
print(np.expand_dims(a, 1).shape)
# (2, 1, 3)
print(np.expand_dims(a, 2).shape)
# (2, 3, 1)
Une valeur négative peut être spécifiée pour le deuxième axe d’argument. -1 correspond à la dernière dimension, et vous pouvez spécifier la position par derrière.
print(np.expand_dims(a, -1).shape)
# (2, 3, 1)
print(np.expand_dims(a, -2).shape)
# (2, 1, 3)
print(np.expand_dims(a, -3).shape)
# (1, 2, 3)
Dans NumPy 1.17, spécifier une valeur telle que axe > a.ndim ou axe < -a.ndim – 1 dans le deuxième argument axe ne provoque pas d’erreur et la dimension est ajoutée à la fin ou au début.
Cependant, comme l’indique le message d’avertissement, cela provoquera une erreur à l’avenir, vous devez donc l’éviter.
print(np.expand_dims(a, 3).shape)
# (2, 3, 1)
#
# /usr/local/lib/python3.7/site-packages/ipykernel_launcher.py:1: DeprecationWarning: Both axis > a.ndim and axis < -a.ndim - 1 are deprecated and will raise an AxisError in the future.
# """Entry point for launching an IPython kernel.
print(np.expand_dims(a, -4).shape)
# (2, 1, 3)
#
# /usr/local/lib/python3.7/site-packages/ipykernel_launcher.py:1: DeprecationWarning: Both axis > a.ndim and axis < -a.ndim - 1 are deprecated and will raise an AxisError in the future.
# """Entry point for launching an IPython kernel.
Seules des valeurs entières peuvent être spécifiées dans le deuxième axe d’argument. Il est impossible d’ajouter plusieurs dimensions à la fois en spécifiant plusieurs positions avec une liste ou un tuple.
# print(np.expand_dims(a, (0, 1)).shape)
# TypeError: '>' not supported between instances of 'tuple' and 'int'
Comme avec np.newaxis, np.expand_dims() renvoie une vue.
a_expand_dims = np.expand_dims(a, 0)
print(np.shares_memory(a, a_expand_dims))
# True
Bien sûr, vous pouvez contrôler la diffusion en ajoutant une nouvelle dimension avec np.expand_dims() comme dans l’exemple de np.newaxis ci-dessus.
np.reshape()
Vous pouvez remodeler ndarray avec la méthode np.reshape() ou reshape() de ndarray. Voir l’article suivant pour plus de détails.
Si vous spécifiez une forme avec une nouvelle dimension à reshape(), le résultat est, bien sûr, le même que lors de l’utilisation de np.newaxis ou np.expand_dims().
a = np.arange(6).reshape(2, 3)
print(a)
# [[0 1 2]
# [3 4 5]]
print(a.shape)
# (2, 3)
print(a[np.newaxis])
# [[[0 1 2]
# [3 4 5]]]
print(a[np.newaxis].shape)
# (1, 2, 3)
print(np.expand_dims(a, 0))
# [[[0 1 2]
# [3 4 5]]]
print(np.expand_dims(a, 0).shape)
# (1, 2, 3)
print(a.reshape(1, 2, 3))
# [[[0 1 2]
# [3 4 5]]]
print(a.reshape(1, 2, 3).shape)
# (1, 2, 3)
Comme vous pouvez le voir dans l’exemple ci-dessus, l’utilisation de np.newaxis et np.expand_dims() présente l’avantage de ne pas avoir à spécifier explicitement la taille de la dimension d’origine.
Même avec reshape(), si vous souhaitez ajouter une dimension au début ou à la fin, vous n’avez pas à spécifier explicitement la taille en décompressant la forme d’origine avec *.
print(a.reshape(1, *a.shape))
# [[[0 1 2]
# [3 4 5]]]
print(a.reshape(1, *a.shape).shape)
# (1, 2, 3)