python & numpy: somme d'une tranche de tableau
J'ai 1 dimensions tableau numpy (array_
) et une liste Python (list_).
Le code suivant fonctionne, mais est inefficace parce que les tranches impliquer une copie superflue (certainement pour Python, les listes, et je crois aussi pour les tableaux numpy?):
result = sum(array_[1:])
result = sum(list_[1:])
Ce qui est une bonne façon de réécrire?
OriginalL'auteur max | 2011-05-05
Vous devez vous connecter pour publier un commentaire.
Trancher un tableau numpy n'est pas faire une copie, comme il le fait dans le cas d'une liste.
Comme un exemple de base:
Cela donne:
Même si nous avons modifié les valeurs dans
y
, c'est juste un point de vue dans la même mémoire quex
.De découpage d'un ndarray renvoie une vue et de ne pas dupliquer la mémoire.
Cependant, il serait beaucoup plus efficace d'utiliser
array_[1:].sum()
plutôt que d'appeler python builtinsum
sur un tableau numpy.Comme une comparaison rapide:
Edit:
Dans le cas de la liste, si pour quelque raison vous ne voulez pas faire une copie, vous pouvez toujours utiliser
itertools.islice
. Au lieu de:que vous pouvez faire:
Dans la plupart des cas, c'est exagéré, cependant. Si vous faites affaire avec des listes assez long pour que la gestion de la mémoire est un enjeu majeur, alors vous ne devriez probablement pas être à l'aide d'une liste pour stocker vos valeurs. (Les listes ne sont pas conçus pour stocker des éléments de manière compacte dans la mémoire.)
Aussi, vous ne voulez pas faire cela pour un tableau numpy. Simplement en faisant
some_array[1:].sum()
seront de plusieurs ordres de grandeur plus rapidement et ne pas utiliser tout plus de mémoire queislice
.sum(x)
est à seulement 5% à 10% plus lent quex.sum()
(surnumpy 1.5.1
). MerciÊtes-vous à l'aide de relativement grande (>1000 éléments) des tableaux? Avec court (~10 éléments) des tableaux, de la somme est à seulement quelques pour cent plus lent, mais au moment où vous vous levez >1000 éléments, c'est une question de quelques microsecondes vs millisecondes. J'ai l'exécuter sur 3 machines avec un matériel différent et différentes versions de python & numpy. Les moments différents, mais la mise à l'échelle les résultats sont similaires. Ils sont à la fois linéaire en temps des algorithmes, mais une itération à travers chaque élément d'un tableau numpy en python (qui est ce que la somme n') est beaucoup plus lent que d'une itération à travers chaque élément de la mémoire tampon dans C (qui est ce que numpy)
Non, même taille que la vôtre. Je vais abuser de la réponse pour un certain temps pour montrer à mes horaires. Merci
comment avez-vous appeler en ligne de commande timeit dans [29] et [30] à partir de l'intérieur de la coquille? Avez-vous démarrer un shell interne est exécuté?
C'est l'un de IPython de la "magie" des fonctions. ipython.scipy.org/moin C'est juste plus pratique que de mettre plein
timeit.timeit
appel avec le programme d'installation, etc... Tout ce qu'il fait, est d'utiliser le code exécuté précédemment dans le shell interactif, comme lesetup
kwarg àtimeit.timeit
. Si vous n'utilisez pas déjà IPython, avoir un coup d'oeil! Il a beaucoup de petites fonctionnalités sympas et macros!OriginalL'auteur Joe Kington
Mon premier instinct était le même que Joe kingston portant quand il s'agit de listes, mais j'ai vérifié, et sur ma machine au moins,
islice
est toujours plus lent!J'ai essayé un
custom_sum
et a trouvé qu'il était plus rapide, mais pas de beaucoup:En outre, au plus grand nombre, c'est plus lent, et de loin!
Je ne pouvais pas penser à autre chose à tester. (Pensées, quelqu'un?)
désolé, j'ai supposé que tu parlais de la vitesse.
Eh bien, en relisant mon post, il semble certainement de cette façon! Je voulais dire l'utilisation de la mémoire, mais ce n'était pas clair du tout dans ce que j'ai écrit. Je suis intrigué à quelle différence il y a... Curieusement, avec d'assez grands listes, il semble que
islice
devient plus rapide encore... Vous avez besoin d' ~1e7 éléments, cependant. J'imagine qu'à ce stade de l'attribution de nouveaux la mémoire devient un goulot d'étranglement. En tout cas ton post est certainement une comparaison intéressante!OriginalL'auteur senderle
@Joe kingston portant (c'est temporaire réponse juste vous montrer mes horaires, je vais l'enlever dès):
Aussi loin que mes numpy(1.5.1) source indique,
sum(.)
est juste un wrapper pourx.sum(.)
. Ainsi, avec de plus grandes entrées de temps d'exécution est le même (asymptotiquement) poursum(.)
etx.sum(.)
.Modifier: Cette réponse a été conçu pour être juste temporaire, mais en fait ça (et ses commentaires) peut en effet être utile à quelqu'un. Donc je vais laisser comme il est tout à l'heure, jusqu'à ce que quelqu'un de vraiment me demander de le supprimer.
sum()
plutôt quenumpy.sum()
. Ce n'est qu'un des pièges de l'utilisationfrom numpy import *
.Oui, j'ai été à dessein de comparer python
sum
de numpy estsum
. Je suppose que l'OP a fait référence à pythonsum
, ainsi. (Il peut très bien ne pas avoir été...) je suis d'accord avec @Sven, ici... C'est exactement pourquoifrom whatever import *
est mauvais, et pourquoi il est particulièrement mauvaise dans le cas d'un espace grand comme numpy! 🙂Aha, OK cela fait (genre de) sens. Cependant, personnellement, je le sentais assez à l'aise de travailler avec
IPython
profilscipy
, même si elle ombrespythons sum(.)
. (Et depuis Joe a l'aide deIPython
ainsi, j'ai juste mal interprété les horaires). BTW, devrais-je supprimer cette réponse ou à laisser (avec des commentaires comme de plus amples explications, OP question)? MerciEh, je pense qu'il clarifie un point que d'autres personnes pourraient être confondus. Je l'avais quitter si c'était moi... Votre appel, même si, bien sûr.
numpy import * ombres
all()
,min()
,max()
,sum()
,any()
,abs()
etround()
. Le plus grand show-bouchons pour moi (même pour l'utilisation interactive) sontany()
etall()
-- le numpy versions ne fonctionnent pas avec le générateur d'expressions. (Je voudrais aussi suggérer de ne pas supprimer cette réponse.)OriginalL'auteur eat
Je ne trouve pas
x[1:].sum()
significativement plus lent quex.sum()
. Pour les listessum(x) - x[0]
est plus rapide quesum(x[1:])
(environ 40% plus rapide OMM).OriginalL'auteur jtniehof