2017-02-07 5 views
2

Ich habe eine Reihe von N-dimensionalen Vektoren.Get Indizes der oberen N Werten in 2D NumPy ndarray oder numpy Matrix

data = np.array([[5, 6, 1], [2, 0, 8], [4, 9, 3]])

In [1]: data 
Out[1]: 
array([[5, 6, 1], 
     [2, 0, 8], 
     [4, 9, 3]]) 

Ich sklearn die mit pairwise_distances function eine Matrix von Abstandswerten zu berechnen. Beachten Sie, dass diese Matrix symmetrisch um die Diagonale ist.

dists = pairwise_distances(data)

In [2]: dists 
Out[2]: 
array([[ 0.  , 9.69535971, 3.74165739], 
     [ 9.69535971, 0.  , 10.48808848], 
     [ 3.74165739, 10.48808848, 0.  ]]) 

ich brauche die Indizes in den oberen N Werten in dieser Matrix entspricht dists, da diese Indizes die paarweise Indizes in data entsprechen wird, die Vektoren mit den größten Abständen zwischen ihnen darstellen.

Ich habe versucht, np.argmax(np.max(distances, axis=1)) tun den Index des max-Wert in jeder Zeile zu erhalten, und np.argmax(np.max(distances, axis=0)) den Index des max-Wert in jeder Spalte zu erhalten, aber beachten Sie, dass:

In [3]: np.argmax(np.max(dists, axis=1)) 
Out[3]: 1 

In [4]: np.argmax(np.max(dists, axis=0)) 
Out[4]: 1 

und:

Da die Matrix um die Diagonale symmetrisch ist, und weil argmax den ersten Index zurückgibt, den sie mit dem maximalen Wert findet, lande ich mit der Zelle in der Diagonalen in der Zeile und Spalte, in der die Max-Werte gespeichert sind. anstelle der Reihe und Spalte der oberen Werte selbst.

An dieser Stelle Ich bin sicher, ich könnte etwas mehr Code schreiben, um die Werte zu finden, die ich suche, aber sicher ist es ein einfacher Weg ich versuche zu tun, was zu tun ist. Also habe ich zwei Fragen, die mehr oder weniger gleichwertig sind:

Wie kann ich die Indizes entsprechend den oberen N Werte in einer Matrix finden, oder, Wie finde ich die Vektoren mit dem Top-N paarweise Entfernungen von einem Array von Vektoren?

Antwort

5

Ich würde Ravel, argsort, und dann entwirren. Ich behaupte nicht, dass dies der beste Weg ist, nur dass es der erste Weg ist, der mir eingefallen ist, und ich werde ihn wahrscheinlich in Schande löschen, nachdem jemand etwas Offensichtlicheres veröffentlicht hat. :-)

Das heißt (die oberen 2-Werte der Auswahl willkürlich):

In [73]: dists = sklearn.metrics.pairwise_distances(data) 

In [74]: dists[np.tril_indices_from(dists, -1)] = 0 

In [75]: dists 
Out[75]: 
array([[ 0.  , 9.69535971, 3.74165739], 
     [ 0.  , 0.  , 10.48808848], 
     [ 0.  , 0.  , 0.  ]]) 

In [76]: ii = np.unravel_index(np.argsort(dists.ravel())[-2:], dists.shape) 

In [77]: ii 
Out[77]: (array([0, 1]), array([1, 2])) 

In [78]: dists[ii] 
Out[78]: array([ 9.69535971, 10.48808848])