2017-05-09 3 views
3

Ich habe zwei multidimensionale Array, sagen wir mal x und y mit 5 Dimensionen und ich würde gerne den Wert von x finden, bei dem die letzte Komponente von y Minima ist. Um die Indizes zu finden, verwende ich einfach I=argmin(y,axis=-1) und dies gibt mir ein 4-dimensionales Array von Indizes zurück. Wie sollte ich die Werte von x für diese Indizes finden? Eine Art von x[I]?Indizierung mehrdimensionaler Arrays mit Argmin-Indizes entlang einer Achse

+0

2 D ... 4 D?Geben Sie etwas Code und etwas Forschung, also können wir eine Idee über haben, über was Sie sprechen –

+0

, was ich habe, ist Axtfeld der Form 'In [87] Form (x) Heraus [87]: (6, 10, 10, 5, 50) ' und ein Array mit den gleichen Abmessungen. Was ich gerne finden würde, sind die Werte von x, für die die letzte Dimension von y minimiert ist. Der erste Schritt ist 'I = argmin (y, axis = -1)', der mir ein Array von Indizes zurückgibt. Nun würde ich gerne wissen, wie zu überprüfen, welche x für diese Indizes entsprechen – gian9

+0

@ gian9 Kannst du x und y Beispiel, sowie gewünschte Ausgabe zur Verfügung stellen? – Nuageux

Antwort

3

Annäherung # 1: Das ist im Grunde advanced-indexing erweitert auf 5D Fall. Um die Dinge ein bisschen bequemer zu machen, können wir die Verwendung von offenem Bereich Arrays mit np.ogrid machen und dann die advanced-indexing ausführen, wie so -

d0,d1,d2,d3,d4 = x.shape 
s0,s1,s2,s3 = np.ogrid[:d0,:d1,:d2,:d3] 
ymin = y[s0,s1,s2,s3,I] 
xmin = x[s0,s1,s2,s3,I] 

Ansatz # 2: Wir können es ein wenig verkürzen, durch die Zusammenführung ersten beiden Schritte mit np.ix_ und haben somit eine generische Funktion von generischen ndarrays Anzahl von Dimensionen zu handhaben -

indxs = np.ix_(*[np.arange(i) for i in x.shape[:-1]]) + (I,) 
ymin = y[indxs] 
xmin = x[indxs] 

Lassen Sie uns einige Beispiele Zufalls bewertet Array verwenden und verifizieren, indem direkt die min entlang letzten Achse mitRechendh y.min(-1) und sie gegen die indizierte Wert ymin aus den vorgeschlagenen Codes zu vergleichen -

In [117]: x = np.random.randint(0,9,(3,4,5,6,7)) 
    ...: y = np.random.randint(0,9,(3,4,5,6,7)) 
    ...: I = np.argmin(y,axis=-1) 
    ...: 

In [118]: d0,d1,d2,d3,d4 = x.shape 
    ...: s0,s1,s2,s3 = np.ogrid[:d0,:d1,:d2,:d3] 
    ...: ymin = y[s0,s1,s2,s3,I] 
    ...: xmin = x[s0,s1,s2,s3,I] 
    ...: 

In [119]: np.allclose(y.min(-1), ymin) 
Out[119]: True 

In [120]: indxs = np.ix_(*[np.arange(i) for i in x.shape[:-1]]) + (I,) 
    ...: ymin = y[indxs] 
    ...: xmin = x[indxs] 
    ...: 

In [121]: np.allclose(y.min(-1), ymin) 
Out[121]: True 
+0

Aber mit diesem Prozess wird die Dimension nicht eingehalten, liege ich falsch? Es wäre vorzuziehen, die Dimension so zu halten, dass die Arrays problemlos gehandhabt werden können. – gian9

+0

@ gian9 Um Dims zu erhalten, können Sie am Ende eine neue Achse anhängen: 'ymin [..., None]' und 'xmin [..., Keine] '. – Divakar

1

Verwendung argmin mit 1 oder 2D-Array ist recht einfach, aber mit 3 oder mehr ist, ist die Abbildung zu verstehen härter:

In [332]: y=np.arange(24) 
In [333]: np.random.shuffle(y) 
In [334]: y=y.reshape(2,3,4) 
In [335]: y 
Out[335]: 
array([[[19, 12, 9, 21], 
     [ 8, 13, 20, 17], 
     [22, 11, 5, 1]], 

     [[ 7, 2, 23, 16], 
     [ 0, 10, 6, 4], 
     [14, 18, 15, 3]]]) 

In [338]: I = np.argmin(y, axis=-1) 
In [339]: I 
Out[339]: 
array([[2, 0, 3], 
     [1, 0, 3]], dtype=int32) 
In [340]: np.min(y, axis=-1) 
Out[340]: 
array([[9, 8, 1], 
     [2, 0, 3]]) 

Das Ergebnis ist (2,3), ein Index für jede Ebene/Zeile.

Die I[0,0] bedeutet, dass y[i,j,I[i,j]] das Minimum in der i,j Zeile ist.

Also brauchen wir einen Weg zu erzeugen, dass i,j Paarung

In [345]: i,j = np.ix_(np.arange(2), np.arange(3)) 
In [346]: i 
Out[346]: 
array([[0], 
     [1]]) 
In [347]: j 
Out[347]: array([[0, 1, 2]]) 

In [349]: y[i,j,I[i,j]] 
Out[349]: 
array([[9, 8, 1], 
     [2, 0, 3]]) 

Oder dass verkürzen:

In [350]: y[i,j,I] 
Out[350]: 
array([[9, 8, 1], 
     [2, 0, 3]]) 

Auch bei 2d das Verfahren ist das gleiche:

In [360]: z=y[:,:,1] 
In [361]: z 
Out[361]: 
array([[12, 13, 11], 
     [ 2, 10, 18]]) 
In [362]: idx=np.argmin(z, axis=-1) 
In [363]: idx 
Out[363]: array([2, 0], dtype=int32) 
In [364]: z[[0,1], idx]  # index the 1st dim with range 
Out[364]: array([11, 2]) 

Mit mgrid könnte es einfacher, um den Prozess machen zu visualisieren:

In [378]: i,j =np.mgrid[0:2,0:3] 
In [379]: i 
Out[379]: 
array([[0, 0, 0], 
     [1, 1, 1]]) 
In [380]: j 
Out[380]: 
array([[0, 1, 2], 
     [0, 1, 2]]) 
In [381]: y[i, j, I] 
Out[381]: 
array([[9, 8, 1], 
     [2, 0, 3]]) 

hier i und j ist (2,3) Arrays, die I in Form entsprechen. Zusammen wählen die 3 Arrays ein (2,3) Array von Elementen aus y.

ix_ und ogrid erzeugen Sie einfach die entsprechenden open Arrays.

Verwandte Themen