Python somme vs NumPy de numpy.somme
Quelles sont les différences dans les performances et le comportement entre l'utilisation de Python natif sum
de fonction NumPy et de numpy.sum
? sum
fonctionne sur NumPy de tableaux et numpy.sum
fonctionne sur Python, les listes et ils reviennent tous les deux le même résultat (n'ai pas testé les cas limites comme dépassement de capacité), mais différents types.
>>> import numpy as np
>>> np_a = np.array(range(5))
>>> np_a
array([0, 1, 2, 3, 4])
>>> type(np_a)
<class 'numpy.ndarray')
>>> py_a = list(range(5))
>>> py_a
[0, 1, 2, 3, 4]
>>> type(py_a)
<class 'list'>
# The numerical answer (10) is the same for the following sums:
>>> type(np.sum(np_a))
<class 'numpy.int32'>
>>> type(sum(np_a))
<class 'numpy.int32'>
>>> type(np.sum(py_a))
<class 'numpy.int32'>
>>> type(sum(py_a))
<class 'int'>
Edit: je pense que ma question ici est, serait à l'aide d' numpy.sum
sur une liste de Python entiers plus rapidement qu'à l'aide de Python propre sum
?
En outre, quelles sont les conséquences (y compris le rendement) de l'aide d'un Python entier par rapport à un scalaire numpy.int32
? Par exemple, pour a += 1
, est-il un comportement ou les performances de la différence si le type de a
est un Python entier ou d'une numpy.int32
? Je suis curieux de savoir si il est plus rapide d'utiliser un NumPy scalaire de type de données telles que numpy.int32
une valeur qui est ajoutée ou soustraite à beaucoup de choses dans le code Python.
Pour plus de précisions, je suis en train de travailler sur un bio-informatique de simulation qui se compose en partie de la réduction de multidimensionnelles numpy.ndarray
s dans les scalaires, les sommes qui sont alors de plus traitées. Je suis à l'aide de Python 3.2 et NumPy 1.6.
Merci d'avance!
Vous devez vous connecter pour publier un commentaire.
Je suis curieuse et chronométré.
numpy.sum
semble beaucoup plus rapide pour les tableaux numpy, mais beaucoup plus lentement sur les listes.Résultat lorsque
x = range(1000)
:Résultat lorsque
x = np.random.standard_normal(1000)
:Je suis à l'aide de Python 2.7.2 et Numpy 1.6.1
np.sum
étant plus rapide lors de l'utilisation denp.array
. Mais si vous avez le tempsnp.sum(np.array object)
etsum(list object)
, à la fois d'effectuer à peu près également.La réponse à cette question est: Non.
Pythons somme sera plus rapide sur les listes, alors que NumPys somme sera plus rapide sur les tableaux. J'ai fait un test pour montrer les timings (Python 3.6, NumPy 1.14):
Avec ces résultats:
Gauche: sur un tableau NumPy; à Droite: sur une liste Python.
Notez que c'est un graphe log-log, car l'indice de référence couvre une très large plage de valeurs. Cependant, pour des résultats qualitatifs: la Baisse des moyens de mieux.
Qui montre que pour les listes de Pythons
sum
est toujours plus rapide tout ennp.sum
ou lasum
méthode de la matrice sera plus rapide (sauf pour de très courts tableaux où les Pythonssum
est plus rapide).Juste au cas où vous êtes intéressé par la comparaison de ces uns contre les autres, j'ai également fait un complot, y compris tous:
Il est intéressant de noter le point de
numpy
peut rivaliser sur les tableaux en Python et listes est à peu près à près de 200 éléments! Notez que ce nombre peut dépendre de beaucoup de facteurs, tels que Python/NumPy version, ... Ne le prenez pas trop à la lettre.Ce qui n'a pas été mentionné, c'est la raison de cette différence (je parle de la grande différence d'échelle pas la différence pour de courtes listes/tableaux où les fonctions n'ont tout simplement différents constant, les frais généraux). En supposant Disponible une liste Python est un wrapper autour d'une C (le langage C) tableau de pointeurs vers des objets Python (dans ce cas, Python entiers). Ces entiers peuvent être considérés comme des wrappers autour d'un entier C (et non pas correcte parce que Python entiers peut être arbitrairement grand, de sorte qu'il ne peut pas simplement utiliser un C entier, mais il est assez proche).
Par exemple une liste comme
[1, 2, 3]
serait (schématiquement, j'en ai laissé un peu de détails) stockés comme ceci:Un tableau NumPy, cependant, est un wrapper autour d'une C tableau contenant les valeurs de C (dans ce cas
int
oulong
selon 32 ou 64 bits et selon le système d'exploitation).Donc un tableau NumPy comme
np.array([1, 2, 3])
devrait ressembler à ceci:La prochaine chose à comprendre, c'est comment ces fonctions de travail:
sum
parcourt la itérable (dans ce cas, la liste ou le tableau) et ajoute tous les éléments.sum
méthode parcourt la stockées C tableau et ajoute ces valeurs de C et enfin enveloppe la valeur dans un Python de type (dans ce casnumpy.int32
(ounumpy.int64
) et le renvoie.sum
fonction convertit l'entrée d'unearray
(au moins si ce n'est pas un tableau déjà), puis utilise le NumPysum
méthode.Clairement en ajoutant les valeurs de C à partir d'un C tableau est beaucoup plus rapide que d'ajouter des objets Python, qui est pourquoi les fonctions de NumPy peut être beaucoup plus rapide (voir le deuxième graphique ci-dessus, le NumPy fonctions sur les tableaux battre le Python somme, de loin, pour de grands tableaux).
Mais la conversion d'une liste Python à un tableau NumPy est relativement lente et alors vous avez encore d'ajouter les valeurs de C. C'est la raison pourquoi listes le Python
sum
sera plus rapide.La seule question est: pourquoi est-Pythons
sum
sur unarray
si lent (c'est le plus lent de tous comparé les fonctions). Et en fait ça a à voir avec le fait que les Pythons somme simplement itère sur tout ce que vous transmettez. Dans le cas d'une liste, on obtient le stockés objet Python mais dans le cas d'un 1D tableau NumPy il n'y a pas stockés des objets Python, juste les valeurs de C, de sorte Python&NumPy devez créer un objet Python (unnumpy.int32
ounumpy.int64
) pour chaque élément, puis de ces objets Python doivent être ajoutés. La création de l'emballage pour la valeur C est ce qui le rend vraiment très lent.J'ai fait quelques tests et pour l'addition et soustractions de scalaires vous devriez certainement bâton avec Python entiers. Même si il peut y avoir des mise en cache de passe ce qui signifie que les tests suivants peuvent ne pas être tout à fait représentatif:
C'est 3 à 6 fois plus rapide à faire scalaire opérations avec Python entiers qu'avec NumPy scalaires. Je n'ai pas vérifié, pourquoi c'est le cas, mais ma conjecture est que NumPy scalaires sont rarement utilisés, et probablement pas optimisée pour la performance.
La différence devient un peu moins si vous avez réellement effectuer des opérations arithmétiques où les deux opérandes sont des numpy scalaires:
Ensuite, c'est seulement 2 fois plus lent.
Dans le cas où vous vous demandiez pourquoi j'ai utilisé
itertools.repeat
ici alors que je pourrais tout simplement utiliséfor _ in range(...)
à la place. La raison en est querepeat
est plus rapide et donc subit moins de frais généraux par boucle. Parce que je suis seulement intéressé par l'addition/soustraction de temps, il est effectivement préférable de ne pas avoir de la boucle de la surcharge de jouer avec les horaires (du moins, pas tant que ça).Numpy devrait être beaucoup plus rapide, surtout quand vos données est déjà un tableau numpy.
Numpy les tableaux sont d'une couche mince sur un standard C tableau. Lorsque numpy somme itère sur ce, il n'est pas de faire la vérification du type et il est très rapide. La vitesse doit être comparables à faire l'opération en utilisant la norme C.
En comparaison, à l'aide de python de la somme qu'il a d'abord convertir le tableau numpy pour un python tableau, puis itérer sur ce tableau. Il doit faire un peu de type de vérification et est généralement plus lente.
Le montant exact que python somme est plus lent que numpy somme n'est pas bien défini que le python somme va être un peu fonction optimisée par rapport à la rédaction de votre propre fonction somme en python.
numpy.sum
peut ont convertir une liste à un tableau numpy, ce qui permettrait d'expliquer les résultats de @Akavall moment là.Noter que Python somme sur multidimensionnelle des tableaux numpy effectuera uniquement une somme le long du premier axe:
C'est une extension de la réponse post ci-dessus par Akavall. À partir de cette réponse, vous pouvez voir que
np.sum
effectue plus rapidement pournp.array
des objets, alors quesum
effectue plus rapidement pourlist
objets. Pour élargir que:Sur l'exécution
np.sum
pour unnp.array
objet Vs.sum
pour unlist
objet, il semble qu'ils obtiennent de cou de cou.Ci-dessus,
sum
est un minuscule peu plus vite quenp.array
, bien que, par moments, j'ai vunp.sum
des horaires à être14.1 µs
, trop. Mais surtout, c'est14.3 µs
.