Znajdowanie średniej z listy


473

Muszę znaleźć średnią listę w Pythonie. To do tej pory mój kod

l = [15, 18, 2, 36, 12, 78, 5, 6, 9]
print reduce(lambda x, y: x + y, l)

Mam go, więc sumuje wartości na liście, ale nie wiem, jak je podzielić?


45
numpy.mean, jeśli możesz sobie pozwolić na instalację numpy
mitch

7
sum(L) / float(len(L)). obsługiwać puste listy w kodzie dzwoniącym, takie jakif not L: ...
n611x007

4
@mitch: nie ma znaczenia, czy stać cię na instalację numpy. numpy to całe słowo samo w sobie. To, czy faktycznie potrzebujesz numpy. Zainstalowanie numpy, rozszerzenia C 16mb, do obliczania średnich byłoby, cóż, bardzo niepraktyczne, dla kogoś, kto nie używałby go do innych celów.
n611x007,

3
zamiast instalować cały pakiet numpy tylko dla avg / mean, jeśli używasz Pythona 3, możemy to zrobić za pomocą modułu statystycznego po prostu przez „ze średniej importu statystyki” lub jeśli na Pythonie 2.7 lub mniej, moduł statystyczny można pobrać z src: hg.python.org/cpython/file/default/Lib/statistics.py doc: docs.python.org/dev/library/statistics.html i używane bezpośrednio.
MHz

Odpowiedzi:


567

W Pythonie 3.4+ możesz używać statistics.mean()

l = [15, 18, 2, 36, 12, 78, 5, 6, 9]

import statistics
statistics.mean(l)  # 20.11111111111111

W starszych wersjach Pythona możesz to zrobić

sum(l) / len(l)

W Pythonie 2 musisz przekonwertować lenna zmiennoprzecinkowe, aby uzyskać podział zmiennoprzecinkowy

sum(l) / float(len(l))

Nie ma potrzeby używania reduce. Jest znacznie wolniejszy i został usunięty w Pythonie 3.


9
Jeśli lista składa się z wskazówki, The wynik pod python 2 będzie int
Mitch

To idealne ! przepraszam za głupie pytanie, ale naprawdę szukałem tego wszędzie! Dziękuję bardzo !
Carla Dessi

7
jak powiedziałem, jestem nowy w tym, myślałem, że będę musiał zrobić to z pętlą lub czymś, aby policzyć liczbę liczb w nim, nie zdawałem sobie sprawy, że mogę po prostu użyć długości. to pierwsza rzecz, którą zrobiłem z pythonem
Carla Dessi

2
co jeśli suma jest masywną liczbą, która nie zmieści się w int / float?
Użytkownik Foo Bar

5
@ FooBarUser, to powinieneś obliczyć k = 1,0 / len (l), a następnie zmniejszyć: zmniejsz (lambda x, y: x + y * k, l)
Arseniy

519
l = [15, 18, 2, 36, 12, 78, 5, 6, 9]
sum(l) / len(l)

63
Jeśli używasz from __future__ import division, możesz wyeliminować to brzydkie float.
S.Lott,

12
Zgoda. floatjest brzydka jak diabli, po prostu chciałam to uprościć.
yprez

39
Innym sposobem na wyeliminowanie tego „brzydkiego” pływaka:sum(l, 0.0) / len(l)
remosu

26
Jako programista w C ++ jest to schludne jak diabli, a float wcale nie jest brzydki!
lahjaton_j

20
W python3 możesz po prostu użyćsum(l) / len(l)
VasiliNovikov

283

Możesz użyć numpy.mean:

l = [15, 18, 2, 36, 12, 78, 5, 6, 9]

import numpy as np
print(np.mean(l))

4
To jest dziwne. Zakładałbym, że byłoby to znacznie bardziej wydajne, ale wydaje się, że zajmuje 8 razy więcej czasu na losowej liście pływaków niż po prostusum(l)/len(l)
L. Amber O'Hearn

8
Och, ale np.array(l).mean()jest znacznie szybszy.
L. Amber O'Hearn,

8
@ L.AmberO'Hearn, po prostu go i czasowym np.mean(l)i np.array(l).meansą o tej samej prędkości, i sum(l)/len(l)jest około dwa razy szybciej. Użyłem l = list(np.random.rand(1000)), bo oczywiście obie numpymetody stają się znacznie szybsze, jeśli tak ljest numpy.array.
Akavall,

11
cóż, chyba że jest to jedyny powód instalacji numpy. instalacja pakietu 16 mb C dowolnej sławy do obliczeń średnich wygląda bardzo dziwnie w tej skali.
n611x007,

ale w mojej opinii. nie trzeba dbać o prędkość w normalnych warunkach ..
Tyan

230

Statystyki moduł został dodany do Pythona 3.4 . Ma funkcję obliczania średniej zwanej średnią . Przykład z podaną listą to:

from statistics import mean
l = [15, 18, 2, 36, 12, 78, 5, 6, 9]
mean(l)

28
Jest to najbardziej elegancka odpowiedź, ponieważ wykorzystuje standardowy moduł biblioteczny, który jest dostępny od Pythona 3.4.
Serge Stroobandt,

4
I jest stabilny numerycznie
Antti Haapala

I to powoduje błąd ładniejszy jeśli przypadkowo przechodzić w pustej listy statistics.StatisticsError: mean requires at least one data pointzamiast bardziej tajemnicze ZeroDivisionError: division by zerodo sum(x) / len(x)rozwiązania.
Boris

45

Dlaczego miałbyś używać reduce()tego, skoro Python ma doskonale chrupiącą sum()funkcję?

print sum(l) / float(len(l))

(Jest float()to konieczne, aby zmusić Python do dokonania podziału zmiennoprzecinkowego.)


34
Dla tych z nas, którzy są nowi w słowie „cromulent”
RolfBly

1
float()nie jest konieczne w Pythonie 3.
Boris

36

Jeśli używasz Pythona> = 3.4, istnieje biblioteka statystyk

https://docs.python.org/3/library/statistics.html

Możesz użyć metody podanej w ten sposób. Załóżmy, że masz listę liczb, których średnią chcesz znaleźć: -

list = [11, 13, 12, 15, 17]
import statistics as s
s.mean(list)

Ma też inne metody, takie jak stdev, wariancja, tryb, średnia harmoniczna, mediana itp., Które są zbyt przydatne.


18

Zamiast rzutować na zmiennoprzecinkowe, możesz dodać 0,0 do sumy:

def avg(l):
    return sum(l, 0.0) / len(l)

10

sum(l) / float(len(l)) jest właściwą odpowiedzią, ale tylko dla kompletności możesz obliczyć średnią za pomocą jednego zmniejszenia:

>>> reduce(lambda x, y: x + y / float(len(l)), l, 0)
20.111111111111114

Pamiętaj, że może to spowodować niewielki błąd zaokrąglenia:

>>> sum(l) / float(len(l))
20.111111111111111

Rozumiem, że to tylko dla zabawy, ale zwrócenie 0 dla pustej listy może nie być najlepszą rzeczą
Johan Lundberg

1
@JohanLundberg - Możesz zamienić 0 na False jako ostatni argument, reduce()który dałby Ci False dla pustej listy, w przeciwnym razie średnia jak poprzednio.
Andrew Clark,

@AndrewClark, dlaczego zmuszasz floatsię len?
EndermanAPM

8

Próbowałem użyć powyższych opcji, ale nie działałem. Spróbuj tego:

from statistics import mean

n = [11, 13, 15, 17, 19]

print(n)
print(mean(n))

pracował na Pythonie 3.5


6

Lub stosowanie pandasjest Series.meanmetoda:

pd.Series(sequence).mean()

Próbny:

>>> import pandas as pd
>>> l = [15, 18, 2, 36, 12, 78, 5, 6, 9]
>>> pd.Series(l).mean()
20.11111111111111
>>> 

Z dokumentów:

Series.mean(axis=None, skipna=None, level=None, numeric_only=None, **kwargs)

A oto dokumenty na ten temat:

https://pandas.pydata.org/pandas-docs/stable/generated/pandas.Series.mean.html

I cała dokumentacja:

https://pandas.pydata.org/pandas-docs/stable/10min.html


To nie jest pytanie o pandę, więc importowanie tak ciężkiej biblioteki wydaje się nadmierne w przypadku prostej operacji, takiej jak znalezienie środka.
cs95

4

Miałem podobne pytanie do rozwiązania w przypadku problemów Udacity. Zamiast wbudowanej funkcji kodowałem:

def list_mean(n):

    summing = float(sum(n))
    count = float(len(n))
    if n == []:
        return False
    return float(summing/count)

Znacznie dłużej niż zwykle, ale dla początkującego jest to dość trudne.


1
Dobrze. Każda inna odpowiedź nie zauważyła zagrożenia pustej listy!
wsysuper

1
Zwracanie False(odpowiednik liczby całkowitej 0) jest najgorszym możliwym sposobem obsługi tego błędu. Lepiej złapać ZeroDivisionErrori wychować coś lepszego (być może ValueError).
uprzejmie

@kindall, w jaki sposób jest ValueErrorlepszy od ZeroDivisionError? To drugie jest bardziej szczegółowe, a ponadto wydaje się, że złapanie błędu arytmetycznego nie jest konieczne, aby ponownie rzucić inny.
MatTheWhale

Ponieważ ZeroDivisionErrorjest przydatna tylko jeśli wiesz jak kalkulacja jest wykonywana (czyli, że podział przez długość listy jest zaangażowany). Jeśli tego nie wiesz, to nie mówi ci, na czym polega problem z przekazaną wartością. Podczas gdy twój nowy wyjątek może zawierać te bardziej szczegółowe informacje.
kindall

4

jako początkujący właśnie kodowałem to:

L = [15, 18, 2, 36, 12, 78, 5, 6, 9]

total = 0

def average(numbers):
    total = sum(numbers)
    total = float(total)
    return total / len(numbers)

print average(L)

Bravo: IMHO, sum(l)/len(l)jest zdecydowanie najbardziej elegancką odpowiedzią (nie trzeba wykonywać konwersji typów w Pythonie 3).
fralau

4

Jeśli chcesz uzyskać więcej niż tylko średnią (aka średnią), możesz sprawdzić scipy statystyki

from scipy import stats
l = [15, 18, 2, 36, 12, 78, 5, 6, 9]
print(stats.describe(l))

# DescribeResult(nobs=9, minmax=(2, 78), mean=20.11111111111111, 
# variance=572.3611111111111, skewness=1.7791785448425341, 
# kurtosis=1.9422716419666397)

3

Aby użyć reducedo obliczenia średniej bieżącej, musisz śledzić całkowitą, ale także całkowitą liczbę elementów do tej pory widoczną. ponieważ nie jest to trywialny element na liście, musisz również reducepodać dodatkowy argument, aby go spasować.

>>> l = [15, 18, 2, 36, 12, 78, 5, 6, 9]
>>> running_average = reduce(lambda aggr, elem: (aggr[0] + elem, aggr[1]+1), l, (0.0,0))
>>> running_average[0]
(181.0, 9)
>>> running_average[0]/running_average[1]
20.111111111111111

1
ciekawe, ale nie o to prosił.
Johan Lundberg

3

Oba mogą dać ci zbliżone wartości na liczbach całkowitych lub co najmniej 10 wartości dziesiętnych. Ale jeśli naprawdę zastanawiasz się nad długimi zmiennymi wartościami, obie mogą być różne. Podejście może się różnić w zależności od tego, co chcesz osiągnąć.

>>> l = [15, 18, 2, 36, 12, 78, 5, 6, 9]
>>> print reduce(lambda x, y: x + y, l) / len(l)
20
>>> sum(l)/len(l)
20

Wartości zmiennoprzecinkowe

>>> print reduce(lambda x, y: x + y, l) / float(len(l))
20.1111111111
>>> print sum(l)/float(len(l))
20.1111111111

@Andrew Clark miał rację w swoim zeznaniu.


3

Przypuszczam, że

x = [[-5.01,-5.43,1.08,0.86,-2.67,4.94,-2.51,-2.25,5.56,1.03], [-8.12,-3.48,-5.52,-3.78,0.63,3.29,2.09,-2.13,2.86,-3.33], [-3.68,-3.54,1.66,-4.11,7.39,2.08,-2.59,-6.94,-2.26,4.33]]

możesz zauważyć, że xma wymiar 3 * 10, jeśli potrzebujesz dostać się meando każdego wiersza, możesz to wpisać

theMean = np.mean(x1,axis=1)

nie zapomnij import numpy as np


1
l = [15, 18, 2, 36, 12, 78, 5, 6, 9]

l = map(float,l)
print '%.2f' %(sum(l)/len(l))

3
Nieskuteczny. Konwertuje wszystkie elementy na ruchome przed ich dodaniem. Szybsza jest konwersja samej długości.
Chris Koston

1

Znajdź średnią na liście za pomocą następującego kodu PYTHON :

l = [15, 18, 2, 36, 12, 78, 5, 6, 9]
print(sum(l)//len(l))

spróbuj tego łatwo.


0
print reduce(lambda x, y: x + y, l)/(len(l)*1.0)

lub jak opublikowano wcześniej

sum(l)/(len(l)*1.0)

1.0 ma zapewnić podział zmiennoprzecinkowy


0

Łącząc kilka powyższych odpowiedzi, wymyśliłem następujące, które działają z redukcją i nie zakładają, że masz Ldostęp do funkcji redukcji:

from operator import truediv

L = [15, 18, 2, 36, 12, 78, 5, 6, 9]

def sum_and_count(x, y):
    try:
        return (x[0] + y, x[1] + 1)
    except TypeError:
        return (x + y, 2)

truediv(*reduce(sum_and_count, L))

# prints 
20.11111111111111

0

Chcę dodać tylko inne podejście

import itertools,operator
list(itertools.accumulate(l,operator.add)).pop(-1) / len(l)

-5
numbers = [0,1,2,3]

numbers[0] = input("Please enter a number")

numbers[1] = input("Please enter a second number")

numbers[2] = input("Please enter a third number")

numbers[3] = input("Please enter a fourth number")

print (numbers)

print ("Finding the Avarage")

avarage = int(numbers[0]) + int(numbers[1]) + int(numbers[2]) + int(numbers [3]) / 4

print (avarage)

co jeśli użytkownik doda liczby zmiennoprzecinkowe do tablicy? Wyniki będą bardzo nieprecyzyjne.
Flame_Phoenix
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.