0
votes

Un moyen rapide de faire des calculs un à tous consécutifs sur des tableaux numpus sans boucle?

Je travaille sur un problème d'optimisation, mais pour éviter d'entrer dans les détails, je vais fournir un exemple simple d'un bug qui me donne des maux de tête pendant quelques jours.

Dis avoir un 2D tableau NUMPY avec des coordonnées XY observées: P>

z = list(map(find_sum, x, y))


3 commentaires

Où est-ce que distance.CityBlock vient? On dirait qu'il serait important de toute solution. Voir aussi: exemple de reproductible minimal .


Ah désolé! Merci pour la prise. Ont édité la question à inclure une importation de distance de scipy.optimize .


Formidable! Je ne serai probablement que pour regarder demain cependant, il est tard :)


3 Réponses :


2
votes

Cette solution implémente la distance dans numpy code>, comme je pense que c'est un bon exemple de diffusion , qui est une chose très utile de savoir si vous devez utiliser des tableaux et des matrices.

Par définition de la distance de Manhattan, vous devez évaluer la somme de la valeur absolue de la différence entre chaque colonne. Toutefois, la première colonne de x code>, x [:, 0] code>, a la forme (4,) et la première colonne de y code>, y [:, 0] code>, a la forme (2,), de sorte qu'elles ne sont pas compatibles dans le sens de l'application de la soustraction: la propriété de radiodiffusion indique que chaque forme est comparée à partir des dimensions de fin et deux dimensions sont Compatible quand ils sont égaux ou l'un d'entre eux est 1. Malheureusement, aucun d'entre eux n'est vrai pour vos colonnes. P>

Cependant, vous pouvez ajouter une nouvelle dimension de la valeur 1 à l'aide de np.newaxis code>, donc p> xxx pré>

est tableau ([1, 2, 4, 5]) code>, mais p> xxx

est p> xxx pré>

et sa forme est (4, 1). Maintenant, une matrice de forme (4, 1) soustraite par une matrice de forme 2 entraîne une matrice de forme (4, 2), par Traitement de diffusion code> ( p>

print(np.abs(x[:, np.newaxis] - y).sum(axis=(1, 2)))


0 commentaires

1
votes

Voici comment vous pouvez le faire à l'aide d'une émission numpy avec une explication simplifiée

Ajustez la forme pour la diffusion forte> p>

start_points = np.array([[1,2], [2,3], [4,5], [5,6]])
dest_points = np.array([[11,13], [12, 14]])
np.sum(np.abs(start_points[np.newaxis, :, :] - dest_points[:, np.newaxis, :]), axis=(0,2))


0 commentaires

0
votes

Avec tant de lignes, vous pouvez faire des économies substantielles en utilisant un algorithme intelligent. Laissez-nous pour la simplicité supposer qu'il n'y a qu'une seule dimension; Une fois que nous avons établi l'algorithme, revenir à l'affaire général est une simple question de résumer sur les coordonnées.

L'algorithme naïf est O (mn) code> où m, n code > sont les tailles des ensembles x, y code>. Notre algorithme est O ((m + n) journal (m + n)) code> il échoue beaucoup mieux. P>

Nous devons d'abord trier l'union de x et y code> par coordonnée puis formez le cumsum code> sur y code>. Ensuite, nous trouvons pour chaque x x code> le nombre ybefx code> de y dans y code> à sa gauche et utilisez-le pour rechercher le Cumsum code> élément ybefxval code>. Les distances résumées à tous y code> à gauche de x code> sont ybefx code> coordonnées de x code> moins ybefxval code>, les distances à tous les y code> à droite sont la somme de tous les coordonnées y code> ybefxval code> moins n - ybefx Coordonnée Times de X code>. P>

Où est-ce que la sauvetage vient? Les coordonnées de tri nous permettent de recycler les sommations que nous avons faites auparavant, au lieu de commencer à chaque fois à partir de zéro. Cela utilise le fait que jusqu'à un signe que nous résumons toujours les mêmes coordonnées Y code> et allant de gauche à droite les panneaux retournez un par un. P>

code: p> xxx pré>

exécution de l'échantillon, comparer Smart Algo "Trier" à Naive Algo implémentées à l'aide de Cadon code> Fonction de la bibliothèque: p>

same result: True
sort       : 1.4447695480193943 ms
scipy cdist: 36.41934019047767 ms


0 commentaires