Wie erhält man in Übereinstimmung mit "Es gibt nur einen offensichtlichen Weg, dies zu tun" die Größe eines Vektors (1D-Arrays) in Numpy?
def mag(x):
return math.sqrt(sum(i**2 for i in x))
Das Obige funktioniert, aber ich kann nicht glauben, dass ich selbst eine solche triviale und Kernfunktion spezifizieren muss.
linalg.norm
wie unten erwähnt. Aber etwas einfacher als Ihr Lambda-Ding, ohne dass Importe erforderlich sind, ist nursum(x*x)**0.5
def
wenn ich eine solche Funktion deklariere? Ich denke, wenn es legitimerweise eine Zeile ist, erleichtert es das Lesen.Antworten:
Die Funktion, nach der Sie suchen, ist
numpy.linalg.norm
. (Ich denke, es sollte in Base Numpy als Eigenschaft eines Arrays sein - sagen wirx.norm()
- aber na ja ).Sie können auch eine Option
ord
für die gewünschte Norm n-ter Ordnung eingeben. Angenommen, Sie wollten die 1-Norm:Und so weiter.
quelle
Matrix.randn([5,5])
np.linalg.norm
jetzt ein neuesaxis
Argument, das hier diskutiert wird: stackoverflow.com/a/19794741/1959808Wenn Sie sich Sorgen um die Geschwindigkeit machen, sollten Sie stattdessen Folgendes verwenden:
Hier einige Benchmarks:
EDIT: Die wirkliche Geschwindigkeitsverbesserung kommt, wenn Sie die Norm vieler Vektoren nehmen müssen. Für die Verwendung von reinen Numpy-Funktionen sind keine for-Schleifen erforderlich. Beispielsweise:
quelle
np.linalg.norm
ein Engpass war, aber dann bin ich noch einen Schritt weiter gegangen und habe nur eine Methode verwendet,math.sqrt(x[0]**2 + x[1]**2)
die eine weitere signifikante Verbesserung darstellt.numpy.linalg.norm
enthält Schutzmaßnahmen gegen Überlauf, die diese Implementierung überspringt. Versuchen Sie beispielsweise, die Norm von zu berechnen[1e200, 1e200]
. Es gibt einen Grund, wenn es langsamer ist ...inf
beim Rechnennp.linalg.norm([1e200,1e200])
.Eine weitere Alternative besteht darin, die
einsum
Funktion in numpy für beide Arrays zu verwenden:oder Vektoren:
Es scheint jedoch einen gewissen Overhead mit dem Aufrufen zu geben, der es bei kleinen Eingaben langsamer machen kann:
quelle
numpy.linalg.norm
enthält Schutzmaßnahmen gegen Überlauf, die diese Implementierung überspringt. Versuchen Sie beispielsweise, die Norm von zu berechnen[1e200, 1e200]
. Es gibt einen Grund, wenn es langsamer ist ...Der schnellste Weg, den ich gefunden habe, ist über inner1d. So vergleicht es sich mit anderen Numpy-Methoden:
inner1d ist ~ 3x schneller als linalg.norm und ein Haar schneller als einsum
quelle
linalg.norm
ist es das schnellste, da 9 Anrufe in 29 ms getätigt werden, also 1 Anruf in 3,222 ms gegenüber 1 Anruf in 4,5 ms fürinner1d
.((10**8,3,))
und dann manuell ausführen ,np.linalg.norm(V,axis=1)
indem gefolgtnp.sqrt(inner1d(V,V))
, werden Sie feststellen ,linalg.norm
wird hinken im Vergleich zu inner1dnumpy.linalg.norm
enthält Schutzmaßnahmen gegen Überlauf, die diese Implementierung überspringt. Versuchen Sie beispielsweise, die Norm von zu berechnen[1e200, 1e200]
. Es gibt einen Grund, wenn es langsamer ist ...verwenden , um die Funktion norm in scipy.linalg (oder numpy.linalg )
quelle
Sie können dies mit dem Toolbelt vg präzise tun . Es ist eine leichte Schicht über Numpy und unterstützt einzelne Werte und gestapelte Vektoren.
Ich habe die Bibliothek bei meinem letzten Start erstellt, wo sie durch solche Verwendungen motiviert war: einfache Ideen, die in NumPy viel zu ausführlich sind.
quelle