Numpy에서 벡터의 크기를 어떻게 구하나요?
"명백한 방법은 하나뿐"이라는 말에 따라 Numpy에서 벡터(1D 어레이)의 크기를 구하는 방법은 무엇입니까?
def mag(x):
return math.sqrt(sum(i**2 for i in x))
위와 같이 동작합니다만, 이러한 사소하고 핵심적인 기능을 스스로 지정해야 한다는 것을 믿을 수 없습니다.
원하는 함수는 (배열 속성으로서 기본 numpy여야 합니다.x.norm()
--하지만, 아, 그렇구나).
import numpy as np
x = np.array([1,2,3,4,5])
np.linalg.norm(x)
옵션 입력도 가능합니다.ord
원하는 n차 규범에 대한 것입니다.1-norm을 원한다고 가정해 보십시오.
np.linalg.norm(x,ord=1)
기타 등등.
속도가 조금이라도 걱정되는 경우 대신 다음을 사용해야 합니다.
mag = np.sqrt(x.dot(x))
벤치마크를 몇 가지 소개합니다.
>>> import timeit
>>> timeit.timeit('np.linalg.norm(x)', setup='import numpy as np; x = np.arange(100)', number=1000)
0.0450878
>>> timeit.timeit('np.sqrt(x.dot(x))', setup='import numpy as np; x = np.arange(100)', number=1000)
0.0181372
편집: 진정한 속도 향상은 많은 벡터의 표준을 취해야 할 때 이루어집니다.루프에는 순수 numpy 함수를 사용할 필요가 없습니다.예를 들어 다음과 같습니다.
In [1]: import numpy as np
In [2]: a = np.arange(1200.0).reshape((-1,3))
In [3]: %timeit [np.linalg.norm(x) for x in a]
100 loops, best of 3: 4.23 ms per loop
In [4]: %timeit np.sqrt((a*a).sum(axis=1))
100000 loops, best of 3: 18.9 us per loop
In [5]: np.allclose([np.linalg.norm(x) for x in a],np.sqrt((a*a).sum(axis=1)))
Out[5]: True
또 다른 대안은 다음과 같습니다.einsum
다음 중 하나의 어레이에 대해 numpy로 기능합니다.
In [1]: import numpy as np
In [2]: a = np.arange(1200.0).reshape((-1,3))
In [3]: %timeit [np.linalg.norm(x) for x in a]
100 loops, best of 3: 3.86 ms per loop
In [4]: %timeit np.sqrt((a*a).sum(axis=1))
100000 loops, best of 3: 15.6 µs per loop
In [5]: %timeit np.sqrt(np.einsum('ij,ij->i',a,a))
100000 loops, best of 3: 8.71 µs per loop
또는 벡터:
In [5]: a = np.arange(100000)
In [6]: %timeit np.sqrt(a.dot(a))
10000 loops, best of 3: 80.8 µs per loop
In [7]: %timeit np.sqrt(np.einsum('i,i', a, a))
10000 loops, best of 3: 60.6 µs per loop
다만, 콜에 관련하는 오버헤드가 있어, 작은 입력으로 속도가 저하하는 경우가 있습니다.
In [2]: a = np.arange(100)
In [3]: %timeit np.sqrt(a.dot(a))
100000 loops, best of 3: 3.73 µs per loop
In [4]: %timeit np.sqrt(np.einsum('i,i', a, a))
100000 loops, best of 3: 4.68 µs per loop
가장 빨리 찾을 수 있는 방법은 inner1d입니다.다른 numpy 메서드와의 비교는 다음과 같습니다.
import numpy as np
from numpy.core.umath_tests import inner1d
V = np.random.random_sample((10**6,3,)) # 1 million vectors
A = np.sqrt(np.einsum('...i,...i', V, V))
B = np.linalg.norm(V,axis=1)
C = np.sqrt((V ** 2).sum(-1))
D = np.sqrt((V*V).sum(axis=1))
E = np.sqrt(inner1d(V,V))
print [np.allclose(E,x) for x in [A,B,C,D]] # [True, True, True, True]
import cProfile
cProfile.run("np.sqrt(np.einsum('...i,...i', V, V))") # 3 function calls in 0.013 seconds
cProfile.run('np.linalg.norm(V,axis=1)') # 9 function calls in 0.029 seconds
cProfile.run('np.sqrt((V ** 2).sum(-1))') # 5 function calls in 0.028 seconds
cProfile.run('np.sqrt((V*V).sum(axis=1))') # 5 function calls in 0.027 seconds
cProfile.run('np.sqrt(inner1d(V,V))') # 2 function calls in 0.009 seconds
inner1d는 linalg.norm보다 3배 빠르고 머리카락은 einsum보다 빠릅니다.
scipy.linalg(또는 numpy.linalg)의 함수 규범을 사용합니다.
>>> from scipy import linalg as LA
>>> a = 10*NP.random.randn(6)
>>> a
array([ 9.62141594, 1.29279592, 4.80091404, -2.93714318,
17.06608678, -11.34617065])
>>> LA.norm(a)
23.36461979210312
>>> # compare with OP's function:
>>> import math
>>> mag = lambda x : math.sqrt(sum(i**2 for i in x))
>>> mag(a)
23.36461979210312
툴 벨트 vg를 사용하여 이를 간결하게 수행할 수 있습니다.Numpy 위에 라이트 레이어이며 단일 값과 누적 벡터를 지원합니다.
import numpy as np
import vg
x = np.array([1, 2, 3, 4, 5])
mag1 = np.linalg.norm(x)
mag2 = vg.magnitude(x)
print mag1 == mag2
# True
저는 지난 번 스타트업에서 라이브러리를 만들었습니다.이 라이브러리는 다음과 같은 용도로 사용되었습니다.NumPy에서는 너무 장황한 단순한 아이디어입니다.
1차원 벡터의 예를 다음에 나타냅니다.
x = np.array([1,-2,3,-4,5])
일반적으로 다음과 같이 코드화합니다.
from scipy import linalg
mag = linalg.norm(x)
다양한 유형의 입력(매트릭스 또는 1-D 벡터의 스택(배치))에 대해서는 API를 일관되게 설명하는 참조 문서를 참조하십시오.https://numpy.org/doc/stable/reference/generated/numpy.linalg.norm.html
또는
가상 환경이 최신 상태이고scipy
유형만 누락됨
mag = np.sqrt(x.dot(x))
각 지수를 제곱한 다음, 합하고, 제곱을 취합니다.
import numpy as np
def magnitude(v):
return np.sqrt(np.sum(np.square(v)))
print(magnitude([3,4]))
언급URL : https://stackoverflow.com/questions/9171158/how-do-you-get-the-magnitude-of-a-vector-in-numpy
'programing' 카테고리의 다른 글
구조 선언 끝에 있는 이 [1]의 목적은 무엇입니까? (0) | 2022.09.24 |
---|---|
Java Enumeration과 반복자의 차이점 (0) | 2022.09.24 |
[첫 글자가 B로 시작]에서 모두 선택합니다. (0) | 2022.09.24 |
대소문자를 구분하지 않는 '입력' (0) | 2022.09.24 |
자바스크립트로 div 콘텐츠를 변경하려면 어떻게 해야 하나요? (0) | 2022.09.24 |