programing

Numpy에서 벡터의 크기를 어떻게 구하나요?

itsource 2022. 9. 24. 23:47
반응형

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

반응형