Comment la méthode transpose() de NumPy permute-t-elle les axes d'un tableau?
In [28]: arr = np.arange(16).reshape((2, 2, 4))
In [29]: arr
Out[29]:
array([[[ 0, 1, 2, 3],
[ 4, 5, 6, 7]],
[[ 8, 9, 10, 11],
[12, 13, 14, 15]]])
In [32]: arr.transpose((1, 0, 2))
Out[32]:
array([[[ 0, 1, 2, 3],
[ 8, 9, 10, 11]],
[[ 4, 5, 6, 7],
[12, 13, 14, 15]]])
quand on passe un tuple d'entiers à transpose()
fonction, que se passe-t-il?
pour être précis, il s'agit d'un tableau 3D: Comment num Py transforme-t-il le tableau Quand je passe le tuple des axes (1, 0 ,2)
? Pouvez-vous expliquer quelle ligne ou colonne de ces entiers? Et que sont les nombres d'axes dans le contexte de NumPy?
5 réponses
pour transposer un tableau, num Py échange simplement les informations de forme et de foulée pour chaque axe. Voici les enjambées:
>>> arr.strides
(64, 32, 8)
>>> arr.transpose(1, 0, 2).strides
(32, 64, 8)
notez que l'opération de transposition a permuté les axes 0 et 1. Les longueurs de ces axes ont également été échangées (les deux longueurs sont 2
dans cet exemple).
Aucune donnée n'a besoin d'être copiée pour que cela arrive; NumPy peut simplement changer la façon dont il regarde la mémoire sous-jacente pour construire le nouveau tableau.
Visualiser les progrès
La foulée de la valeur représente le nombre d'octets qui doit être parcouru dans la mémoire afin d'atteindre la valeur suivante d'un axe d'un tableau.
maintenant, notre tableau 3D arr
regarde ce (étiquetés axes):
Ce tableau est stocké dans un bloc contigu de mémoire; essentiellement il est unidimensionnel. Pour l'interpréter comme une 3D objet, NumPy doit sauter par-dessus un certain nombre constant d'octets pour se déplacer le long de l'un des trois axes:
puisque chaque entier prend 8 octets de mémoire (nous utilisons le type int64 dtype), la valeur de foulée pour chaque dimension est 8 fois le nombre de valeurs que nous devons sauter. Par exemple, pour se déplacer le long de l'axe 1, quatre valeurs (32 octets) sont sautées, et pour se déplacer le long de l'axe 0, huit valeurs (64 octets) doivent être sauter.
Quand on écrit arr.transpose(1, 0, 2)
nous échangeons les axes 0 et 1. Le tableau transposé ressemble à ceci:
Tout ce que NumPy a besoin de faire est d'échanger les informations de foulée pour l'axe 0 et l'axe 1 (l'axe 2 est inchangé). Maintenant, nous devons aller plus loin pour nous déplacer le long de l'axe 1 que l'axe 0:
ce concept de base fonctionne pour toute permutation des axes d'un tableau. Réel le code qui traite la transposition est écrit en C et peut être trouvé ici.
Comme expliqué dans la documentation:
Par défaut, inverser les dimensions, sinon permuter les axes selon les valeurs fournies.
ainsi vous pouvez passer un paramètre optionnel axes
définir l'ordre des dimensions.
E. g. transposant les deux premières dimensions de l'espace RVB VGA réseau de pixels:
>>> x = np.ones((480, 640, 3))
>>> np.transpose(x, (1, 0, 2)).shape
(640, 480, 3)
en notation C, votre tableau serait:
int arr[2][2][4]
qui est un tableau 3D ayant 2 tableaux 2D. Chacun de ces tableaux 2D a 2 tableau 1D, chacun de ces tableaux 1D a 4 éléments.
vous avez donc trois dimensions. Les axes sont 0, 1, 2, avec des tailles 2, 2, 4. C'est exactement comme num PY traite les axes d'un réseau n-dimensionnel.
Donc, arr.transpose((1, 0, 2))
prendre de l'axe 1 et de le mettre en position 0, l'axe 0 et de le mettre en position 1 et l'axe 2 et de la laisser dans la position 2. Vous êtes effectivement en permutant les axes:
0 -\/-> 0
1 -/\-> 1
2 ----> 2
En d'autres termes, 1 -> 0, 0 -> 1, 2 -> 2
. Les axes de destination sont toujours dans l'ordre, donc tout ce dont vous avez besoin est de spécifier les axes source. Lisez le tuple dans cet ordre:(1, 0, 2)
.
Dans ce cas, votre nouveau tableau de dimensions sont de nouveau [2][2][4]
, seulement parce que les axes 0 et 1 avaient la même taille (2).
plus intéressant est une transposition de (2, 1, 0)
qui vous donne un tableau de [4][2][2]
.
0 -\ /--> 0
1 --X---> 1
2 -/ \--> 2
En d'autres termes, 2 -> 0, 1 -> 1, 0 -> 2
. Lisez le tuple dans cet ordre:(2, 1, 0)
.
>>> arr.transpose((2,1,0))
array([[[ 0, 8],
[ 4, 12]],
[[ 1, 9],
[ 5, 13]],
[[ 2, 10],
[ 6, 14]],
[[ 3, 11],
[ 7, 15]]])
vous avez fini avec un int[4][2][2]
.
vous obtiendrez probablement une meilleure compréhension si toutes les dimensions étaient de taille différente, de sorte que vous pourriez voir où chaque axe est allé.
pourquoi le premier élément intérieur [0, 8]
? Parce que si vous visualisez votre tableau 3D comme deux feuilles de papier, 0
et 8
sont alignés, l'un sur un papier et un sur le papier, à la fois dans le coin supérieur gauche. En transposant (2, 1, 0)
vous dites que vous voulez la direction de papier à papier, de maintenant mars le long du papier, de gauche à droite, et l'orientation de gauche à droite pour allez maintenant à partir de papier de papier. Vous aviez 4 éléments allant de gauche à droite, donc maintenant vous avez quatre morceaux de papier à la place. Et vous aviez 2 papiers, donc maintenant vous avez 2 éléments allant de gauche à droite.
désolé pour le terrible art ASCII. ¯\_(ツ)_/¯
.remodelage (num1, num2, num3).... les trois nombres correspondent à num1 = 0, num2 = 1 et num3 = 2. Ainsi dans la transposition, avoir (2.0.1) signifie tourner autour de l'ordre d'origine de num1,num2 et num3.
.reshape works like .reshape(5,5,2)
^ ^ ^
| | |
I want 5,5x2's
ex.
variable.remodeler(5,5,2)
...
...
.transpose(2,0,1) // vraiment les moyens de refaire remodeler(2,5,5)...ce qui veut dire que je veux 2, 5x5 matrices
- toute la documentation dans le monde ne pouvait pas être claire jusqu'à ce que je l'ai testé avec:
import numpy as np
arr = np.arange(50).reshape(5,5,2)
print(arr)
arr3d = arr.transpose(2,0,1)
print(arr3d)
-cela dit, en utilisant ma théorie, Je ne sais pas pourquoi avoir .transpose (1.0,2) ne donne pas une sortie qui ressemble à l'original, changer un 5 avec un 5 ne devrait rien faire, mais il fait ceci:
[[[ 0 1]
[10 11]
[20 21]
[30 31]
[40 41]]
[[ 2 3]
[12 13]
[22 23]
[32 33]
[42 43]]
[[ 4 5]
[14 15]
[24 25]
[34 35]
[44 45]]
[[ 6 7]
[16 17]
[26 27]
[36 37]
[46 47]]
[[ 8 9]
[18 19]
[28 29]
[38 39]
[48 49]]]
- mon intsructeur sur udemy n'a pas pu expliquer pourquoi ou comment (1,0,2) faire cela.
Pour résumer
a = np.array( range(24), int).reshape((2,3,4))
a.shape gives (2,3,4)
a.transpose().shape gives (4,3,2) shape tuple is reversed.
a = np.tableau( range(24), de type int).reshape ((2,3,4))
A [i,j,k] égale A. transpose((2,0,1))[k,i,j]
l'axe 0 prend la 2e place
l'axe 1 qui prend la 3ème place
axe 2 contes de la 1ère place
bien sûr, nous devons prendre soin que les valeurs le paramètre tuple passé à transposer est unique et dans la plage (nombre d'axes)