Je souhaite implémenter l'expression suivante en Python:
où et sont des tableaux numpy de taille , et est un tableau numpy de taille . La taille peut aller jusqu'à environ 10000, et la fonction fait partie d'une boucle interne qui sera évaluée plusieurs fois, donc la vitesse est importante.
Idéalement, j'aimerais éviter complètement une boucle for, même si je suppose que ce n'est pas la fin du monde s'il y en a une. Le problème est que j'ai du mal à voir comment le faire sans avoir quelques boucles imbriquées, et cela risque de le rendre plutôt lent.
Quelqu'un peut-il voir comment exprimer l'équation ci-dessus en utilisant numpy d'une manière efficace et de préférence également lisible? Plus généralement, quelle est la meilleure façon d'aborder ce genre de chose?
Réponses:
Voici la solution Numba. Sur ma machine, la version Numba est> 1000x plus rapide que la version python sans le décorateur (pour une matrice 200x200, 'k' et un vecteur de longueur 200 'a'). Vous pouvez également utiliser le décorateur @autojit qui ajoute environ 10 microsecondes par appel afin que le même code fonctionne avec plusieurs types.
Divulgation: je suis l'un des développeurs de Numba.
la source
Voici un début. Tout d'abord, mes excuses pour toute erreur.
J'ai expérimenté quelques approches différentes. J'étais un peu confus par les limites de la somme - la limite supérieure devrait-elle être , plutôt que i - 1 ?je i - 1
Edit: Non, la limite supérieure était correcte comme indiqué dans la question. Je l'ai laissé tel quel, car une autre réponse utilise maintenant le même code, mais la correction est simple.
D'abord une version en boucle:
Je l'ai fait une seule boucle avec des tranches numpy:
La version numpy avec une boucle explicite est environ 25 fois plus rapide sur mon ordinateur lorsque .n = 5000
Ensuite, j'ai écrit une version Cython du code en boucle (plus lisible).
Sur mon ordinateur portable, celui-ci est environ 200 fois plus rapide que la version en boucle (et 8 fois plus rapide que la version vectorisée à 1 boucle). Je suis sûr que les autres peuvent faire mieux.
J'ai joué avec une version Julia, et elle semblait (si je la chronométrais correctement) comparable au code Cython.
la source
Ce que vous voulez semble être une convolution; Je pense que le moyen le plus rapide d'y parvenir serait la
numpy.convolve
fonction.Vous devrez peut-être fixer les indices en fonction de vos besoins exacts, mais je pense que vous aimeriez essayer quelque chose comme:
la source