Wie kann ich Elemente aus der 3D-Matrix mit bestimmten Indizes in numpy abrufen?
- Ich habe eine 3D-Matrix, im folgenden Beispiel ist es eine (5, 4, 2) Matrix:
data_matrix
- Ich habe ein anderes Indexarray der Form (5, 4), wobei jede Arrayreihe die Elementposition darstellt:
indx_array
Ich weiß nicht, wie ich das bekommen kann required_output
. Ich versuche, (1,2) Elemente jeder Zeile basierend auf dem anzuordnenindx_array
Ich möchte nicht für Schleifen verwenden!
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]]
]
BEARBEITEN: Aktualisiert indx_array
, um die Situation besser zu veranschaulichen.
Antworten
- Numpy: Indizierung
- Numpy: Indizieren mehrdimensionaler Arrays
In [637]: data_matrix.shape
Out[637]: (5, 4, 2)
In [638]: indx_array.shape
Out[638]: (5, 4)
Sie benötigen eine erweiterte Indizierung für die ersten beiden Dimensionen. Das Array der ersten Dimension muss mit dem zweiten (5,4) senden. Dazu mache ich eine (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]]])
Vergleichen Sie meinen (5,1) Index mit dem akzeptierten _x
(der (5,4) verwüstet ist):
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])
Beim Senden _x
braucht der nicht die Wiederholung (5,4); (5,1) ist genug.
Broadcasting macht eine virtuelle Wiederholung. Dies kann mit der broadcast_to
Funktion veranschaulicht werden:
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)
Es sind diese 0
Schritte, die sich wiederholen, ohne Kopien zu machen. as_strided
ist die nützlichste stride_tricks
Funktion, insbesondere beim Verschieben von Fenstern. Normalerweise lassen wir den automatischen Rundfunk die Arbeit erledigen, ohne uns zu viele Gedanken darüber zu machen, wie.
Kann mit ein wenig Übergabe des Index-Arrays durchgeführt werden.
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)
was zu dem erwarteten numpy Array führt
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]]])