Obliczanie średniej arytmetycznej (jeden typ średniej) w Pythonie


267

Czy w Pythonie jest wbudowana lub standardowa metoda biblioteczna do obliczania średniej arytmetycznej (jeden typ średniej) z listy liczb?


Średnia jest dwuznaczna - tryb i mediana są również często używanymi średnimi
jtlz2

Tryb i mediana to inne miary tendencji centralnej. Nie są to średnie. Tryb ten jest najczęściej spotykaną wartością w zestawie danych i niekoniecznie jest unikalny. Mediana to wartość reprezentująca środek punktów danych. Jak sugeruje to pytanie, istnieje kilka różnych typów średnich, ale wszystkie różnią się od obliczeń mediany i trybu. purplemath.com/modules/meanmode.htm
Jarom

@Jarom Ten link nie zgadza się z tobą: „Średnia, mediana i tryb to trzy rodzaje„ średnich ”
Marcelo Cantos

Odpowiedzi:


284

Nic nie wiem w standardowej bibliotece. Możesz jednak użyć czegoś takiego:

def mean(numbers):
    return float(sum(numbers)) / max(len(numbers), 1)

>>> mean([1,2,3,4])
2.5
>>> mean([])
0.0

W numpy jest numpy.mean().


20
Powszechną rzeczą jest uznanie, że średnia []to 0, co można zrobić float(sum(l))/max(len(l),1).
yo „

8
PEP 8 mówi, że ljest to zła nazwa zmiennej, ponieważ tak bardzo przypomina 1. Również wolałbym użyć if lniż if len(l) > 0. Zobacz tutaj
zondo,

1
Dlaczego dzwoniłeś max?
1 -_-

3
Zobacz pytanie powyżej: Aby uniknąć dzielenia przez zero (dla [])
Simon Fakir

5
Puste listy nie mają znaczenia. Proszę, nie udawaj, że tak.
Marcelo Cantos,

193

NumPy ma numpy.meanśrednią arytmetyczną. Użycie jest tak proste:

>>> import numpy
>>> a = [1, 2, 4]
>>> numpy.mean(a)
2.3333333333333335

6
numpy to koszmar do zainstalowania w virtualenv. Naprawdę powinieneś rozważyć nieużywanie tego lib
vcarel

46
@vcarel: „numpy to koszmar do zainstalowania w virtualenv”. Nie jestem pewien, dlaczego to mówisz. Kiedyś tak było, ale przez ostatni rok lub dłużej było to bardzo łatwe.

6
Muszę poprzeć ten komentarz. Obecnie używam numpy w virtualenv w OSX i absolutnie nie ma problemu (obecnie używam CPython 3.5).
Juan Carlos Coto

4
W systemach ciągłej integracji, takich jak Travis CI, instalacja numpy zajmuje kilka dodatkowych minut. Jeśli szybka i lekka kompilacja jest dla Ciebie cenna i potrzebujesz tylko środka, zastanów się.
Akseli Palén,

2
@ Środowiska wirtualne AkseliPalén w Travis CI mogą korzystać z numpy zainstalowanego przez apt-get przy użyciu pakietów witryny systemowej . Może być wystarczająco szybki do użycia, nawet jeśli ktoś potrzebuje tylko środka.
Bengt,

184

Użyj statistics.mean:

import statistics
print(statistics.mean([1,2,4])) # 2.3333333333333335

Jest dostępny od wersji Python 3.4. Dla użytkowników 3.1-3.3 stara wersja modułu jest dostępna w PyPI pod nazwą stats. Po prostu zmień statisticsna stats.


2
Zauważ, że jest to bardzo wolne w porównaniu do innych rozwiązań. Porównać timeit("numpy.mean(vec)), timeit("sum(vec)/len(vec)")i timeit("statistics.mean(vec)")- ten ostatni jest wolniejszy niż inni przez ogromny czynnik (> 100 w niektórych przypadkach na moim komputerze). Wydaje się, że wynika to ze szczególnie precyzyjnej implementacji sumoperatora statistics, patrz PEP i Kodeks . Nie jestem jednak pewien przyczyny dużej różnicy wydajności między statistics._sumi numpy.sum.
jhin

10
@jhin to dlatego, że statistics.meanpróbuje być poprawny . Oblicza poprawnie średnią [1e50, 1, -1e50] * 1000.
Antti Haapala

1
statistics.meanzaakceptuje również generator wartości wyrażenia, na którym dławią się wszystkie rozwiązania stosowane len()dla dzielnika.
PaulMcG

54

Nie potrzebujesz nawet numpy ani scipy ...

>>> a = [1, 2, 3, 4, 5, 6]
>>> print(sum(a) / len(a))
3

24
wtedy średnia ([2,3]) dałaby 2. uważaj na zmiennoprzecinkowe. Lepsze użycie float (suma (l)) / len (l). Jeszcze lepiej, uważaj, aby sprawdzić, czy lista jest pusta.
jesusiniesta

14
@jesusiniesta, z wyjątkiem python3, gdzie podział wykonuje to, co powinien: divide
yota

11
A w Python 2.2+, jeśli jesteś from __future__ import divisionna szczycie swojego programu
spiffytech

Co z dużymi liczbami i przepełnieniem?
obayhan

Co a = list()? Proponowany kod powoduje ZeroDivisionError.
Ioannis Filippidis


7

Zamiast rzucać na spławik, możesz wykonać następujące czynności

def mean(nums):
    return sum(nums, 0.0) / len(nums)

lub za pomocą lambda

mean = lambda nums: sum(nums, 0.0) / len(nums)

AKTUALIZACJE: 15.12.2019

Python 3.8 dodał funkcję fmean do modułu statystyk . Co jest szybsze i zawsze zwraca liczbę zmiennoprzecinkową.

Konwertuj dane na zmiennoprzecinkowe i oblicz średnią arytmetyczną.

Działa to szybciej niż funkcja mean () i zawsze zwraca liczbę zmiennoprzecinkową. Dane mogą być sekwencją lub iterowalne. Jeśli wejściowy zestaw danych jest pusty, wywołuje błąd StatisticsError.

fmean ([3.5, 4.0, 5.25])

4.25

Nowości w wersji 3.8.


2
from statistics import mean
avarage=mean(your_list)

na przykład

from statistics import mean

my_list=[5,2,3,2]
avarage=mean(my_list)
print(avarage)

i wynik jest

3.0

1
def avg(l):
    """uses floating-point division."""
    return sum(l) / float(len(l))

Przykłady:

l1 = [3,5,14,2,5,36,4,3]
l2 = [0,0,0]

print(avg(l1)) # 9.0
print(avg(l2)) # 0.0

1
def list_mean(nums):
    sumof = 0
    num_of = len(nums)
    mean = 0
    for i in nums:
        sumof += i
    mean = sumof / num_of
    return float(mean)

0

Zawsze przypuszczałem, że avgjest pominięty w wbudowanym / stdlib, ponieważ jest tak prosty jak

sum(L)/len(L) # L is some list

a wszelkie zastrzeżenia zostaną już uwzględnione w kodzie dzwoniącym do użytku lokalnego .

Ważne zastrzeżenia:

  1. wynik bez liczby zmiennoprzecinkowej: w python2 9/4 to 2. w celu rozwiązania, użycia float(sum(L))/len(L)lubfrom __future__ import division

  2. dzielenie przez zero: lista może być pusta. rozwiązać:

    if not L:
        raise WhateverYouWantError("foo")
    avg = float(sum(L))/len(L)

0

Prawidłowa odpowiedź na twoje pytanie to użycie statistics.mean. Ale dla zabawy, oto wersja środka, która nie korzysta z len()funkcji, więc (podobnie jak statistics.mean) może być używana w generatorach, które nie obsługują 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)))

-2

Inni już opublikowali bardzo dobre odpowiedzi, ale niektórzy ludzie mogą nadal szukać klasycznego sposobu na znalezienie Mean (avg), więc tutaj zamieszczam (kod przetestowany w Pythonie 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
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.