Calcul de la moyenne arithmétique (un type de moyenne) en Python
268
Existe-t-il une méthode de bibliothèque intégrée ou standard en Python pour calculer la moyenne arithmétique (un type de moyenne) d'une liste de nombres?
La moyenne est ambiguë - le mode et la médiane sont également des moyennes couramment utilisées
jtlz2
Le mode et la médiane sont d'autres mesures de la tendance centrale. Ce ne sont pas des moyennes. Le mode est la valeur la plus courante observée dans un ensemble de données et n'est pas nécessairement unique. La médiane est la valeur qui représente le centre des points de données. Comme la question l'indique, il existe différents types de moyennes, mais tous diffèrent des calculs de médiane et de mode. purplemath.com/modules/meanmode.htm
Jarom
@Jarom Ce lien n'est pas d'accord avec vous: 'La moyenne, la médiane et le mode sont trois types de "moyennes"'
Marcelo Cantos
Réponses:
285
Je ne suis au courant de rien dans la bibliothèque standard. Cependant, vous pouvez utiliser quelque chose comme:
numpy est un cauchemar à installer dans un virtualenv. Vous devriez vraiment envisager de ne pas utiliser cette lib
vcarel
46
@vcarel: "numpy est un cauchemar à installer dans un virtualenv". Je ne sais pas pourquoi tu dis ça. C'était le cas auparavant, mais depuis un an ou plus, cela a été très facile.
6
Je dois appuyer ce commentaire. J'utilise actuellement numpy dans un virtualenv dans OSX, et il n'y a absolument aucun problème (en utilisant actuellement CPython 3.5).
Juan Carlos Coto
4
Avec des systèmes d'intégration continue comme Travis CI, l'installation de numpy prend plusieurs minutes supplémentaires. Si une construction rapide et légère vous est précieuse et que vous n'avez besoin que de la moyenne, considérez.
Il est disponible depuis Python 3.4. Pour les utilisateurs 3.1-3.3, une ancienne version du module est disponible sur PyPI sous le nom stats. Changez simplement statisticsen stats.
Notez que cela est extrêmement lent par rapport aux autres solutions. Comparez timeit("numpy.mean(vec)), timeit("sum(vec)/len(vec)")et timeit("statistics.mean(vec)")- ce dernier est plus lent que les autres par un facteur énorme (> 100 dans certains cas sur mon PC). Cela semble être dû à une implémentation particulièrement précise de l' sumopérateur dans statistics, voir PEP et Code . Je ne suis pas sûr de la raison de la grande différence de performances entre statistics._sumet numpy.sum, cependant.
jhin
10
@jhin c'est parce que le statistics.meanessaye d'être correct . Il calcule correctement la moyenne de [1e50, 1, -1e50] * 1000.
Antti Haapala
1
statistics.meanacceptera également une expression de générateur de valeurs, que toutes les solutions qui utilisent len()pour le diviseur s'étoufferont.
PaulMcG
54
Vous n'avez même pas besoin d'engourdi ou de scipy ...
alors moyenne ([2,3]) donnerait 2. soyez prudent avec les flotteurs. Mieux vaut utiliser float (sum (l)) / len (l). Mieux encore, veillez à vérifier si la liste est vide.
jesusiniesta
14
@jesusiniesta sauf en python3, où la division fait ce qu'elle est censée faire: diviser
yota
11
Et en Python 2.2+ si vous êtes from __future__ import divisionau sommet de votre programme
spiffytech
Qu'en est-il des grands nombres et des débordements?
obayhan
Et alors a = list()? Le code proposé se traduit par ZeroDivisionError.
Au lieu de lancer pour flotter, vous pouvez suivre
def mean(nums):return sum(nums,0.0)/ len(nums)
ou en utilisant lambda
mean =lambda nums: sum(nums,0.0)/ len(nums)
MISES À JOUR: 2019-12-15
Python 3.8 a ajouté la fonction fmean au module de statistiques . Ce qui est plus rapide et renvoie toujours float.
Convertissez les données en flottants et calculez la moyenne arithmétique.
Cela s'exécute plus rapidement que la fonction mean () et renvoie toujours un flottant. Les données peuvent être une séquence ou itérables. Si l'ensemble de données d'entrée est vide, déclenche une StatisticsError.
La bonne réponse à votre question est d'utiliser statistics.mean. Mais pour le plaisir, voici une version de mean qui n'utilise pas la len()fonction, donc elle (comme statistics.mean) peut être utilisée sur des générateurs, qui ne supportent pas len():
from functools import reduce
from operator import truediv
def ave(seq):return truediv(*reduce(lambda a, b:(a[0]+ b[1], b[0]),
enumerate(seq, start=1),(0,0)))
D'autres ont déjà posté de très bonnes réponses, mais certaines personnes pourraient toujours chercher un moyen classique de trouver Mean (avg), alors ici je poste ceci (code testé en Python 3.6):
def meanmanual(listt):
mean =0
lsum =0
lenoflist = len(listt)for i in listt:
lsum += i
mean = lsum / lenoflist
return float(mean)
a =[1,2,3,4,5,6]
meanmanual(a)Answer:3.5
Réponses:
Je ne suis au courant de rien dans la bibliothèque standard. Cependant, vous pouvez utiliser quelque chose comme:
En numpy, il y a
numpy.mean()
.la source
[]
est0
, ce qui peut être fait parfloat(sum(l))/max(len(l),1)
.l
c'est un mauvais nom de variable car il ressemble tellement1
. Aussi, j'utiliseraisif l
plutôt queif len(l) > 0
. Voir icimax
?NumPy a un
numpy.mean
qui est une moyenne arithmétique. L'utilisation est aussi simple que cela:la source
Utilisation
statistics.mean
:Il est disponible depuis Python 3.4. Pour les utilisateurs 3.1-3.3, une ancienne version du module est disponible sur PyPI sous le nom
stats
. Changez simplementstatistics
enstats
.la source
timeit("numpy.mean(vec))
,timeit("sum(vec)/len(vec)")
ettimeit("statistics.mean(vec)")
- ce dernier est plus lent que les autres par un facteur énorme (> 100 dans certains cas sur mon PC). Cela semble être dû à une implémentation particulièrement précise de l'sum
opérateur dansstatistics
, voir PEP et Code . Je ne suis pas sûr de la raison de la grande différence de performances entrestatistics._sum
etnumpy.sum
, cependant.statistics.mean
essaye d'être correct . Il calcule correctement la moyenne de[1e50, 1, -1e50] * 1000
.statistics.mean
acceptera également une expression de générateur de valeurs, que toutes les solutions qui utilisentlen()
pour le diviseur s'étoufferont.Vous n'avez même pas besoin d'engourdi ou de scipy ...
la source
from __future__ import division
au sommet de votre programmea = list()
? Le code proposé se traduit parZeroDivisionError
.Utilisez scipy:
la source
Au lieu de lancer pour flotter, vous pouvez suivre
ou en utilisant lambda
MISES À JOUR: 2019-12-15
Python 3.8 a ajouté la fonction fmean au module de statistiques . Ce qui est plus rapide et renvoie toujours float.
la source
par exemple
et le résultat est
la source
Exemples:
la source
la source
J'ai toujours supposé qu'il
avg
est omis dans les buildins / stdlib car c'est aussi simple queet toute mise en garde serait déjà traitée dans le code de l'appelant pour une utilisation locale .
Mises en garde notables:
résultat non flottant: en python2, 9/4 est 2. pour résoudre, utiliser
float(sum(L))/len(L)
oufrom __future__ import division
division par zéro: la liste peut être vide. résoudre:
la source
La bonne réponse à votre question est d'utiliser
statistics.mean
. Mais pour le plaisir, voici une version de mean qui n'utilise pas lalen()
fonction, donc elle (commestatistics.mean
) peut être utilisée sur des générateurs, qui ne supportent paslen()
:la source
D'autres ont déjà posté de très bonnes réponses, mais certaines personnes pourraient toujours chercher un moyen classique de trouver Mean (avg), alors ici je poste ceci (code testé en Python 3.6):
la source