Zgodnie z zasadą „Jest tylko jeden oczywisty sposób, aby to zrobić”, jak uzyskać wielkość wektora (tablica 1D) w Numpy?
def mag(x):
return math.sqrt(sum(i**2 for i in x))
Powyższe działa, ale nie mogę uwierzyć , że muszę sam określić tak banalną i podstawową funkcję.
linalg.norm
jak wspomniano poniżej. Ale nieco prostsze niż twoja lambda, bez konieczności importowania, jest po prostusum(x*x)**0.5
def
podczas deklarowania takiej funkcji? Myślę, że jeśli jest to prawdziwa jedna linijka, ułatwia to czytanie.Odpowiedzi:
Funkcja, której szukasz, to
numpy.linalg.norm
. (Myślę, że powinno to być w base numpy jako właściwość tablicy - powiedzmyx.norm()
- ale no cóż).Możesz również wprowadzić opcjonalną
ord
normę n-tego rzędu, którą chcesz. Powiedzmy, że chciałeś normy 1:I tak dalej.
źródło
Matrix.randn([5,5])
np.linalg.norm
ma teraz nowyaxis
argument, omówiony tutaj: stackoverflow.com/a/19794741/1959808Jeśli w ogóle martwisz się o prędkość, powinieneś zamiast tego użyć:
Oto kilka testów porównawczych:
EDYCJA: Prawdziwa poprawa prędkości następuje, gdy musisz przyjąć normę dla wielu wektorów. Używanie czystych funkcji numpy nie wymaga żadnych pętli for. Na przykład:
źródło
np.linalg.norm
jest to wąskie gardło, ale potem poszedłem o krok dalej i po prostu zastosowałem,math.sqrt(x[0]**2 + x[1]**2)
co było kolejną znaczącą poprawą.numpy.linalg.norm
zawiera zabezpieczenia przed przepełnieniem, które ta implementacja pomija. Na przykład spróbuj obliczyć normę[1e200, 1e200]
. Jest powód, jeśli wolniej ...inf
podczas przetwarzanianp.linalg.norm([1e200,1e200])
.Jeszcze inną alternatywą jest użycie
einsum
funkcji numpy dla obu tablic:lub wektory:
Wydaje się jednak, że z wywoływaniem go wiąże się pewien narzut, który może spowolnić go przy małych wejściach:
źródło
numpy.linalg.norm
zawiera zabezpieczenia przed przepełnieniem, które ta implementacja pomija. Na przykład spróbuj obliczyć normę[1e200, 1e200]
. Jest powód, jeśli wolniej ...Najszybszy sposób, jaki znalazłem, to Internal1d. Oto, jak wypada to w porównaniu z innymi metodami numpy:
inner1d jest ~ 3x szybsze niż linalg.norm i włos szybciej niż einsum
źródło
linalg.norm
jest najszybszy, ponieważ wykonuje 9 połączeń w 29 ms, więc 1 połączenie w 3,222 ms w porównaniu do 1 połączenia w 4,5 msinner1d
.((10**8,3,))
a następnie uruchom ręcznie,np.linalg.norm(V,axis=1)
a następnienp.sqrt(inner1d(V,V))
zauważyszlinalg.norm
opóźnienie w porównaniu do inner1dnumpy.linalg.norm
zawiera zabezpieczenia przed przepełnieniem, które ta implementacja pomija. Na przykład spróbuj obliczyć normę[1e200, 1e200]
. Jest powód, jeśli wolniej ...użyj normy funkcji w scipy.linalg (lub numpy.linalg )
źródło
Możesz to zrobić zwięźle za pomocą paska narzędzi vg . Jest to lekka warstwa na wierzchu numpy i obsługuje pojedyncze wartości i ułożone wektory.
Bibliotekę stworzyłem podczas mojego ostatniego uruchomienia, gdzie była motywowana takimi zastosowaniami: prostymi pomysłami, które są zbyt szczegółowe w NumPy.
źródło