En accord avec le "Il n'y a qu'une seule façon évidente de le faire", comment obtenir la magnitude d'un vecteur (tableau 1D) dans Numpy?
def mag(x):
return math.sqrt(sum(i**2 for i in x))
Ce qui précède fonctionne, mais je ne peux pas croire que je doive spécifier moi-même une fonction aussi triviale et fondamentale.
linalg.norm
comme mentionné ci-dessous. Mais un peu plus simple que votre truc lambda, sans importation nécessaire, est justesum(x*x)**0.5
def
lors de la déclaration d'une fonction comme ça? Je pense que si c'est légitimement une ligne, cela facilite la lecture.Réponses:
La fonction que vous recherchez est
numpy.linalg.norm
. (Je pense qu'il devrait être en base numpy en tant que propriété d'un tableau - disonsx.norm()
- mais bon).Vous pouvez également ajouter une option
ord
pour la norme de nième ordre que vous souhaitez. Disons que vous vouliez la norme 1:Etc.
la source
Matrix.randn([5,5])
np.linalg.norm
maintenant un nouvelaxis
argument, discuté ici: stackoverflow.com/a/19794741/1959808Si vous vous inquiétez du tout de la vitesse, vous devriez plutôt utiliser:
Voici quelques repères:
EDIT: La véritable amélioration de la vitesse survient lorsque vous devez prendre la norme de nombreux vecteurs. L'utilisation de fonctions numpy pures ne nécessite aucune boucle for. Par exemple:
la source
np.linalg.norm
s'agissait d'un goulot d'étranglement, mais je suis ensuite allé plus loin et j'ai simplement utilisémath.sqrt(x[0]**2 + x[1]**2)
ce qui était une autre amélioration significative.numpy.linalg.norm
contient des garanties contre les débordements que cette implémentation ignore. Par exemple, essayez de calculer la norme de[1e200, 1e200]
. Il y a une raison si c'est plus lent ...inf
lors de l'informatiquenp.linalg.norm([1e200,1e200])
.Une autre alternative consiste à utiliser la
einsum
fonction dans numpy pour l'un ou l'autre des tableaux:ou vecteurs:
Cependant, il semble y avoir une surcharge associée à son appel qui peut le ralentir avec de petites entrées:
la source
numpy.linalg.norm
contient des garanties contre les débordements que cette implémentation ignore. Par exemple, essayez de calculer la norme de[1e200, 1e200]
. Il y a une raison si c'est plus lent ...Le moyen le plus rapide que j'ai trouvé est via inner1d. Voici comment cela se compare aux autres méthodes numpy:
inner1d est ~ 3x plus rapide que linalg.norm et un cheveu plus rapide que einsum
la source
linalg.norm
c'est le plus rapide car il fait 9 appels en 29 ms, donc 1 appel en 3,222 ms contre 1 appel en 4,5 ms pourinner1d
.((10**8,3,))
puis exécutez manuellementnp.linalg.norm(V,axis=1)
suivi denp.sqrt(inner1d(V,V))
, vous remarquerez unlinalg.norm
décalage par rapport à inner1dnumpy.linalg.norm
contient des garanties contre les débordements que cette implémentation ignore. Par exemple, essayez de calculer la norme de[1e200, 1e200]
. Il y a une raison si c'est plus lent ...utiliser la fonction norm dans scipy.linalg (ou numpy.linalg )
la source
Vous pouvez le faire de manière concise en utilisant le toolbelt vg . C'est une couche légère au-dessus de numpy et il prend en charge les valeurs uniques et les vecteurs empilés.
J'ai créé la bibliothèque lors de ma dernière startup, où elle était motivée par des usages comme celui-ci: des idées simples et beaucoup trop verbeuses dans NumPy.
la source