J'ai une variable, x, qui est de la forme (2,2,50,100).
J'ai également un tableau, y, qui est égal à np.array ([0,10,20]). Une chose étrange se produit lorsque j'indexe x [0,:,:, y].
x = np.full((2,2,50,100),np.nan)
y = np.array([0,10,20])
print(x.shape)
(2,2,50,100)
print(x[:,:,:,y].shape)
(2,2,50,3)
print(x[0,:,:,:].shape)
(2,50,100)
print(x[0,:,:,y].shape)
(3,2,50)
Pourquoi le dernier produit-il (3,2,50) et non (2,50,3)?
Réponses:
C'est ainsi que numpy utilise l'indexation avancée pour diffuser des formes de tableau. Lorsque vous passez un
0
pour le premier index ety
pour le dernier index, numpy diffusera le0
pour avoir la même forme quey
. L'équivalence suivante est:x[0,:,:,y] == x[(0, 0, 0),:,:,y]
. Voici un exempleMaintenant, comme vous transmettez effectivement deux ensembles d'indices, vous utilisez l'API d'indexation avancée pour former (dans ce cas) des paires d'indices.
Qui a une première dimension identique à la longueur de
y
. Voilà ce que vous voyez.Par exemple, regardez un tableau avec 4 dimensions qui sont décrites dans le bloc suivant:
x
a une forme séquentielle vraiment facile à comprendre que nous pouvons maintenant utiliser pour montrer ce qui se passe ...La première dimension est comme avoir 2 classeurs Excel, la deuxième dimension est comme avoir 3 feuilles dans chaque classeur, la troisième dimension est comme avoir 4 lignes par feuille et la dernière dimension est 5 valeurs pour chaque ligne (ou colonnes par feuille).
En le regardant de cette façon, en demandant
x[0,:,:,0]
, c'est le dicton: "dans le premier classeur, pour chaque feuille, pour chaque ligne, donnez-moi la première valeur / colonne."Mais maintenant, avec l'indexation avancée, nous pouvons penser
x[(0,0,0),:,:,y]
à "dans le premier classeur, pour chaque feuille, pour chaque ligne, donnez-moi lay
valeur / colonne. Ok, maintenant faites-le pour chaque valeur dey
"Là où ça devient fou, c'est que numpy diffusera pour correspondre aux dimensions externes du tableau d'index. Donc, si vous voulez faire la même opération que ci-dessus, mais pour les DEUX "classeurs Excel", vous n'avez pas à boucler et à concaténer. Vous pouvez simplement passer un tableau à la première dimension, mais il DOIT avoir une forme compatible.
La transmission d'un entier est diffusée vers
y.shape == (3,)
. Si vous voulez passer un tableau comme premier index, seule la dernière dimension du tableau doit être compatible avecy.shape
. C'est-à-dire que la dernière dimension du premier index doit être soit 3 soit 1.Trouvé une courte explication dans les documents: https://docs.scipy.org/doc/numpy/reference/arrays.indexing.html#combining-advanced-and-basic-indexing
Éditer:
À partir de la question d'origine, pour obtenir une ligne de votre sous-découpage souhaité, vous pouvez utiliser
x[0][:,:,y]
:Cependant, si vous essayez d' affecter à ces sous-tranches, vous devez être très prudent que vous regardez une vue de mémoire partagée du tableau d'origine. Sinon, l'affectation ne concernera pas le tableau d'origine, mais une copie.
La mémoire partagée se produit uniquement lorsque vous utilisez un entier ou une tranche pour sous-définir votre tableau, c'est
x[:,0:3,:,:]
-à- dire oux[0,:,:,1:-1]
.Dans votre question d'origine et mon exemple
y
n'est ni un entier ni une tranche, donc finira toujours par être attribué à une copie de l'original.MAIS! Parce que votre tableau pour
y
peut être exprimé sous la forme d' une tranche, vous POUVEZ réellement obtenir une vue assignable de votre choix via:Ici, nous utilisons la tranche
0:21:10
pour saisir chaque index qui se trouveraitrange(0,21,10)
. Nous devons utiliser21
et non20
parce que le point d'arrêt est exclu de la tranche, tout comme dans larange
fonction.Donc, fondamentalement, si vous pouvez construire une tranche qui correspond à vos critères de sous-découpage, vous pouvez faire une affectation.
la source
Il est appelé
combining advanced and basic indexing
. Danscombining advanced and basic indexing
, numpy fait d'abord l'indexation dans l'indexation avancée et sous-espace / concatène le résultat à la dimension de l'indexation de base.Exemple de documents:
donc, sur
x[0,:,:,y]
,0
ety
sont l'indexation avancée. Ils sont diffusés ensemble pour donner une dimension(3,)
.Cela
(3,)
colle au début des 2e et 3e dimensions pour faire(3, 2, 50)
Pour voir que la 1ère et dernière dimension sont vraiment ensemble diffusent, vous pouvez essayer le changement
0
de[0,1]
voir l'erreur de la radiodiffusionla source