De acuerdo con el "Solo hay una forma obvia de hacerlo", ¿cómo se obtiene la magnitud de un vector (matriz 1D) en Numpy?
def mag(x):
return math.sqrt(sum(i**2 for i in x))
Lo anterior funciona, pero no puedo creer que deba especificar yo mismo una función tan trivial y esencial.
linalg.norm
como se menciona a continuación. Pero un poco más simple que su cosa lambda, sin necesidad de importaciones, es solosum(x*x)**0.5
def
al declarar una función como esa? Creo que si es legítimamente una línea, hace que sea más fácil de leer.Respuestas:
La función que buscas es
numpy.linalg.norm
. (Creo que debería estar en la base numpy como una propiedad de una matriz, por ejemplox.norm()
, pero bueno).También puede alimentar de forma opcional
ord
la norma de enésimo orden que desee. Digamos que quería la norma 1:Y así.
fuente
Matrix.randn([5,5])
np.linalg.norm
ahora tiene un nuevoaxis
argumento, discutido aquí: stackoverflow.com/a/19794741/1959808Si está preocupado por la velocidad, debería usar:
Aquí hay algunos puntos de referencia:
EDITAR: La mejora de la velocidad real se produce cuando tienes que tomar la norma de muchos vectores. El uso de funciones numpy puras no requiere ninguna para bucles. Por ejemplo:
fuente
np.linalg.norm
era un cuello de botella, pero luego fui un paso más allá y simplemente utilicé, lomath.sqrt(x[0]**2 + x[1]**2)
que fue otra mejora significativa.numpy.linalg.norm
contiene protecciones contra el desbordamiento que esta implementación omite. Por ejemplo, intente calcular la norma de[1e200, 1e200]
. Hay una razón si es más lento ...inf
al computarnp.linalg.norm([1e200,1e200])
.Otra alternativa es usar la
einsum
función en numpy para cualquiera de las matrices:o vectores:
Sin embargo, parece haber algo de sobrecarga asociada con la llamada que puede hacerlo más lento con entradas pequeñas:
fuente
numpy.linalg.norm
contiene protecciones contra el desbordamiento que esta implementación omite. Por ejemplo, intente calcular la norma de[1e200, 1e200]
. Hay una razón si es más lento ...La forma más rápida que encontré es a través de inner1d. Así es como se compara con otros métodos numpy:
inner1d es ~ 3 veces más rápido que linalg.norm y un cabello más rápido que einsum
fuente
linalg.norm
es el más rápido ya que hace 9 llamadas en 29 ms, por lo que 1 llamada en 3.222 ms frente a 1 llamada en 4.5 msinner1d
.((10**8,3,))
y luego ejecute manualmentenp.linalg.norm(V,axis=1)
seguido denp.sqrt(inner1d(V,V))
, notarálinalg.norm
un retraso en comparación con inner1dnumpy.linalg.norm
contiene protecciones contra el desbordamiento que esta implementación omite. Por ejemplo, intente calcular la norma de[1e200, 1e200]
. Hay una razón si es más lento ...use la norma de función en scipy.linalg (o numpy.linalg )
fuente
Puede hacer esto de manera concisa usando el toolbelt vg . Es una capa ligera encima de numpy y admite valores individuales y vectores apilados.
Creé la biblioteca en mi último inicio, donde estaba motivada por usos como este: ideas simples que son demasiado detalladas en NumPy.
fuente