Numpy Diffusion pour effectuer la distance euclidienne vectorisé
J'ai matrices 2 x 4 et 3 x 4. Je veux trouver la distance euclidienne entre les lignes, et d'obtenir un 2 x 3 de la matrice à la fin. Voici le code avec une boucle qui calcule la distance euclidienne pour chaque vecteur ligne dans un contre tous b ligne de vecteurs. Comment puis-je faire la même chose sans l'aide de boucles for?
import numpy as np
a = np.array([[1,1,1,1],[2,2,2,2]])
b = np.array([[1,2,3,4],[1,1,1,1],[1,2,1,9]])
dists = np.zeros((2, 3))
for i in range(2):
dists[i] = np.sqrt(np.sum(np.square(a[i] - b), axis=1))
OriginalL'auteur user1835351 | 2015-01-14
Vous devez vous connecter pour publier un commentaire.
Simplement utiliser
np.newaxis
à la bonne place:Simply using np.newaxis at the right place
œuvres? Si vous pouviez commencer par le fait quea
est 2x4 etb
est 3x4, ce serait génial.OriginalL'auteur gg349
Ici sont à l'origine des variables d'entrée:
Un est un 2x4 tableau.
B est une matrice 3x4.
Nous voulons calculer la distance Euclidienne de la matrice de fonctionnement dans une entièrement vectorisé, où
dist[i,j]
contient la distance entre le ie instance dans Une et jth exemple, dans B. Alorsdist
est 2x3 dans cet exemple.La distance
peut manifestement être écrit avec numpy comme
Toutefois, comme indiqué ci-dessus, le problème est que l'élément-sage de la soustraction de l'opération
A-B
implique incompatible tableau des tailles, plus précisément le 2 et 3 dans la première dimension.Dans le but de faire de l'élément de sage soustraction, nous avons à pavé de A ou B afin de satisfaire numpy la diffusion de règles. Je vais choisir de compléter Un avec une dimension supplémentaire, de sorte qu'il devient 2 x 1 x 4, ce qui permet à la tableaux de dimensions de line-up pour la radiodiffusion. Pour en savoir plus sur numpy radiodiffusion, voir la tutoriel dans le manuel scipy et le dernier exemple en ce tutoriel.
Vous pouvez effectuer le remplissage soit avec
np.newaxis
valeur ou avec lanp.reshape
de commande. Je montre à la fois ci-dessous:Comme vous pouvez le voir, en utilisant une approche permettra les dimensions de la ligne. Je vais utiliser la première approche avec
np.newaxis
. Alors maintenant, cela fonctionne pour créer Un B, ce qui est un 2x3x4 tableau:Maintenant, nous pouvons mettre cette différence d'expression dans le
dist
équation pour obtenir le résultat final:Noter que le
sum
est plusaxis=2
, ce qui signifie prendre la somme sur le 2x3x4 tableau du troisième axe (où l'axe de l'id commence par 0).Si vos tableaux sont de petite taille, puis la commande ci-dessus va travailler tout aussi bien. Toutefois, si vous avez de grands tableaux, alors vous risquez de rencontrer des problèmes de mémoire. Notez que dans l'exemple ci-dessus, numpy créées en interne un 2x3x4 tableau pour effectuer la radiodiffusion. Si on généralise Un avoir des dimensions
a x z
et B ont des dimensionsb x z
, puis numpy permettra de créer en interne unea x b x z
tableau pour la radiodiffusion.Nous pouvons éviter la création de cet intermédiaire tableau en faisant des mathématiques la manipulation. Parce que vous êtes le calcul de la distance Euclidienne comme une somme des carrés des différences, nous pouvons profiter de la mathématique fait que la somme des carrés des différences peuvent être réécrites.
Remarque que le moyen terme implique la somme sur élément-sage de multiplication. Cette somme de plus de multiplcations est mieux connu comme un produit scalaire. Parce que A et B sont chacun d'une matrice, alors cette opération est en fait une multiplication matricielle. Nous pouvons donc réécrire le ci-dessus que:
On peut alors écrire la suite de numpy code:
Noter que la réponse ci-dessus est exactement le même que le précédent. Encore une fois, l'avantage ici est que nous n'avez pas besoin de créer l'intermédiaire 2x3x4 tableau pour la radiodiffusion.
Pour l'exhaustivité, nous allons vérifier que les dimensions de chaque terme dans
threeSums
permis de radiodiffusion.Donc, comme prévu, la finale
dist
matrice a de dimensions 2x3.Cette utilisation du produit scalaire en lieu et place de la somme de l'élément de sage multiplication est également discuté dans ce tutoriel.
OriginalL'auteur stackoverflowuser2010
J'ai eu le même problème récemment avec l'apprentissage en profondeur(stanford cs231n,Assignment1),mais lorsque je l'ai utilisé
Il y avait une erreur
Cela signifie que j'ai couru hors de la mémoire(En fait,qui a produit un tableau de 500*5000*1024 au milieu.C'est tellement énorme!)
Pour éviter cette erreur,on peut utiliser une formule pour simplifier:
code:
There are, however, cases where broadcasting is a bad idea because it leads to inefficient use of memory that slows computation.There are, however, cases where broadcasting is a bad idea because it leads to inefficient use of memory that slows computation.
OriginalL'auteur Han Qiu
Cette fonctionnalité est déjà inclus dans scipy spatiale d'un module et je vous recommande de l'utiliser car il sera vectorisé et hautement optimisé sous le capot. Mais, comme le montre la réponse à faire, il ya des façons que vous pouvez faire vous-même.
OriginalL'auteur Oliver W.
À l'aide de numpy.linalg.norme travaille aussi bien avec de la radiodiffusion. La spécification d'une valeur entière pour
axis
va utiliser un vecteur de norme, qui est par défaut norme Euclidienne.OriginalL'auteur merv