Comment puis-je obtenir des éléments de la matrice 3D en utilisant des indices spécifiés dans numpy?
- J'ai une matrice 3D, dans l'exemple ci-dessous, c'est une matrice (5, 4, 2):
data_matrix
- J'ai un autre tableau d'index de forme (5, 4) où chaque ligne de tableau représente l'emplacement de l'élément:
indx_array
Je ne sais pas comment puis-je obtenir le fichier required_output
. J'essaie d'organiser (1,2) les éléments de chaque ligne en fonction duindx_array
Je ne veux pas utiliser de boucles!
data_matrix = np.array([
[[0, 1], [2, 3], [4, 5], [6, 7]],
[[8, 9], [10, 11], [12, 13], [14, 15]],
[[16, 17], [18, 19], [20, 21], [22, 23]],
[[24, 25], [26, 27], [28, 29], [30, 31]],
[[32, 33], [34, 35], [36, 37], [38, 39]]
])
indx_array = np.array([[3,2,1,0], [0,1,2,3], [1,0,3,2], [0,3,1,2], [1,2,3,0]])
# I want following result:
required_output = [
[[6, 7], [4, 5], [2, 3], [0, 1]]
[[8, 9], [10, 11], [12, 13], [14, 15]]
[[18, 19], [16, 17], [22, 23], [20, 21]]
[[24, 25], [30, 31], [26, 27], [28, 29]]
[[34, 35], [36, 37], [38, 39], [32, 33]]
]
EDIT: Mise indx_array
à jour du pour mieux illustrer la situation.
Réponses
- Numpy: indexation
- Numpy: indexation de tableaux multidimensionnels
In [637]: data_matrix.shape
Out[637]: (5, 4, 2)
In [638]: indx_array.shape
Out[638]: (5, 4)
Vous avez besoin d'une indexation avancée sur les 2 premières dimensions. Le premier tableau de dimension doit diffuser avec le second (5,4). Pour ce faire, je fais un (5,1) arange
:
In [639]: data_matrix[np.arange(5)[:,None], indx_array]
Out[639]:
array([[[ 6, 7],
[ 4, 5],
[ 2, 3],
[ 0, 1]],
[[ 8, 9],
[10, 11],
[12, 13],
[14, 15]],
[[18, 19],
[16, 17],
[22, 23],
[20, 21]],
[[24, 25],
[30, 31],
[26, 27],
[28, 29]],
[[34, 35],
[36, 37],
[38, 39],
[32, 33]]])
Comparez mon (5,1) index avec le accepté _x
(qui est (5,4) défilé):
In [640]: np.arange(5)[:,None]
Out[640]:
array([[0],
[1],
[2],
[3],
[4]])
In [641]: _x = np.repeat(np.arange(indx_array.shape[0]),indx_array.shape[1])
In [643]: _x
Out[643]: array([0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4])
Avec la diffusion, le _x
n'a pas besoin de la répétition, (5,4); (5,1) suffit.
La diffusion fait une répétition virtuelle. Ceci peut être illustré avec la broadcast_to
fonction:
In [648]: np.broadcast_to(np.arange(5)[:,None],(5,4))
Out[648]:
array([[0, 0, 0, 0],
[1, 1, 1, 1],
[2, 2, 2, 2],
[3, 3, 3, 3],
[4, 4, 4, 4]])
In [649]: _.strides
Out[649]: (8, 0)
Ce sont ces 0
enjambées qui se répètent sans faire de copies. as_strided
est la stride_tricks
fonction la plus utile , en particulier lors de tâches telles que le déplacement de fenêtres. Habituellement, nous laissons simplement la diffusion automatique faire le travail sans trop se soucier du comment.
Peut être fait avec un peu de remise du tableau d'index.
import numpy as np
_x = np.repeat(np.arange(indx_array.shape[0]),indx_array.shape[1])
_y = indx_array.ravel()
output = data_matrix[_x, _y].reshape(data_matrix.shape)
ce qui donne le tableau numpy attendu
array([[[ 6, 7],
[ 4, 5],
[ 2, 3],
[ 0, 1]],
[[ 8, 9],
[10, 11],
[12, 13],
[14, 15]],
[[18, 19],
[16, 17],
[22, 23],
[20, 21]],
[[24, 25],
[30, 31],
[26, 27],
[28, 29]],
[[34, 35],
[36, 37],
[38, 39],
[32, 33]]])