Нахождение среднего из списка


473

Я должен найти среднее значение списка в Python. Это мой код до сих пор

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

У меня есть, поэтому он складывает значения в списке, но я не знаю, как разделить их на них?


45
numpy.mean, если вы можете позволить себе установку numpy
mitch

7
sum(L) / float(len(L)), обрабатывать пустые списки в коде вызывающего абонента, например,if not L: ...
n611x007,

4
@mitch: дело не в том, можете ли вы позволить себе установку numpy. Numpy это целое слово само по себе. Нужно ли вам на самом деле NumPy. Установка numpy, расширения C на 16 Мб, для вычисления среднего значения была бы очень непрактичной для тех, кто не использует его для других целей.
n611x007

3
вместо того, чтобы устанавливать весь пакет NumPy всего за avg / mean, если вы используете Python 3, мы можем сделать это, используя модуль статистики, просто «из среднего значения импорта статистики» или, если на Python 2.7 или менее, модуль статистики можно загрузить из src: hg.python.org/cpython/file/default/Lib/statistics.py doc: docs.python.org/dev/library/statistics.html и используется напрямую.
МГц

Ответы:


568

На Python 3.4+ вы можете использовать statistics.mean()

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

import statistics
statistics.mean(l)  # 20.11111111111111

На старых версиях Python вы можете сделать

sum(l) / len(l)

В Python 2 вам нужно преобразовать lenв число с плавающей точкой, чтобы получить деление числа с плавающей точкой

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

Там нет необходимости использовать reduce. Это намного медленнее и было удалено в Python 3.


9
если список состоит из целых чисел, результатом под python 2 будет int
mitch

Отлично ! извините за глупый вопрос, но я искренне искал это везде! Спасибо вам большое !
Карла Десси

7
Как я уже сказал, я новичок в этом, я думал, что мне нужно сделать это с помощью цикла или чего-то еще, чтобы посчитать количество чисел в нем, я не знал, что могу просто использовать длину. это первое, что я сделал с питоном ..
Карла Десси

2
Что делать, если сумма - это огромное число, которое не помещается в int / float?
Пользователь Foo Bar

5
@FooBarUser тогда вы должны вычислить k = 1,0 / лен (л), а затем уменьшить: уменьшить (лямбда х, у: х + у * к, л)
Арсений

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

63
Если вы используете from __future__ import division, вы можете устранить это безобразное float.
С.Лотт

12
Согласовано. floatужасен, просто хотел, чтобы все было проще.
yprez

39
Еще один способ устранить этот «уродливый» поплавок:sum(l, 0.0) / len(l)
remosu

26
Как программист на C ++, это чертовски мило, а не просто ужасно!
lahjaton_j

20
В python3 вы можете просто использоватьsum(l) / len(l)
VasiliNovikov

283

Вы можете использовать numpy.mean:

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

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

4
Это странно. Я бы предположил, что это будет намного эффективнее, но, похоже, это займет в 8 раз больше времени в случайном списке чисел, чем простоsum(l)/len(l)
L. Amber O'Hearn

8
Да, но np.array(l).mean()это намного быстрее.
Л. Амбер О'Хирн,

8
@ L.AmberO'Hearn, я просто засек и np.mean(l)и np.array(l).meanпримерно с той же скоростью, и sum(l)/len(l)примерно в два раза быстрее. Я использовал l = list(np.random.rand(1000)), конечно, оба numpyметода стали намного быстрее, если lесть numpy.array.
Akavall

11
ну, если только это не единственная причина для установки NumPy. установка 16-мегабайтного C-пакета любой известности для вычисления среднего значения в этом масштабе выглядит очень странно.
n611x007

но на мой взгляд. нет необходимости заботиться о скорости в нормальном состоянии ..
Тян

230

Модуль статистики был добавлен в Python 3.4 . У него есть функция для вычисления среднего, называемого средним . Пример с предоставленным вами списком будет:

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

28
Это самый элегантный ответ, потому что он использует стандартный модуль библиотеки, который доступен начиная с python 3.4.
Серж Строобандт

4
И это численно стабильнее
Антти Хаапала

И это приводит к ошибке лучше , если вы случайно пройти в пустом списке statistics.StatisticsError: mean requires at least one data pointвместо более загадочного ZeroDivisionError: division by zeroдля sum(x) / len(x)решения.
Борис

45

Зачем вам использовать reduce()это, когда Python имеет совершенно громоздкую sum()функцию?

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

( float()Необходимо заставить Python выполнять деление с плавающей запятой.)


34
Для тех из нас, кто плохо знаком
RolfBly

1
float()не нужно на Python 3.
Борис

36

Есть библиотека статистики, если вы используете python> = 3.4

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

Вы можете использовать это подлый метод, как это. Допустим, у вас есть список чисел, которые вы хотите найти среднее:

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

У него есть и другие методы, такие как stdev, дисперсия, мода, среднее гармоническое, медиана и т. Д., Которые слишком полезны.


18

Вместо того, чтобы бросать в плавающее, вы можете добавить 0.0 к сумме:

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

10

sum(l) / float(len(l)) это правильный ответ, но просто для полноты вы можете вычислить среднее значение с одним уменьшением:

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

Обратите внимание, что это может привести к небольшой ошибке округления:

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

Я понимаю, что это просто для удовольствия, но возвращение 0 для пустого списка может быть не лучшим решением
Йохан Лундберг

1
@JohanLundberg - Вы можете заменить 0 на False в качестве последнего аргумента, reduce()который даст вам False для пустого списка, в противном случае среднее значение, как раньше.
Эндрю Кларк

@AndrewClark почему вы заставляете floatна len?
EndermanAPM

8

Я попытался использовать варианты выше, но не сработало. Попробуй это:

from statistics import mean

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

print(n)
print(mean(n))

работал на питоне 3.5


6

Или используйте pandas«s Series.meanметод:

pd.Series(sequence).mean()

Демо-версия:

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

Из документов:

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

И вот документы для этого:

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

И вся документация:

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


Это не вопрос панд, поэтому кажется чрезмерным импортировать такую ​​тяжелую библиотеку для такой простой операции, как поиск среднего значения.
cs95

4

У меня был похожий вопрос для решения проблем Udacity. Вместо встроенной функции я написал:

def list_mean(n):

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

Гораздо дольше, чем обычно, но для новичка это довольно сложно.


1
Хорошо. Любой другой ответ не заметил опасности пустого списка!
wsysuper

1
Возвращение False(эквивалентное целому числу 0) - это наихудший из возможных способов справиться с этой ошибкой. Лучше поймать ZeroDivisionErrorи поднять что-нибудь получше (возможно ValueError).
добро пожаловать

@ kindall как ValueErrorлучше, чем ZeroDivisionError? Последний является более конкретным, и, кроме того, кажется, что нет необходимости отлавливать арифметическую ошибку только для того, чтобы перебросить другую.
MatTheWhale

Потому что ZeroDivisionErrorэто полезно, только если вы знаете, как выполняется вычисление (т. Е. Используется деление на длину списка). Если вы этого не знаете, это не скажет вам, в чем проблема со значением, которое вы передали. В то время как ваше новое исключение может включать эту более конкретную информацию.
любезно

4

как новичок, я только что написал это:

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)

Браво: ИМХО, sum(l)/len(l)безусловно, самый элегантный ответ (нет необходимости делать преобразования типов в Python 3).
Fralau

4

Если вы хотите получить больше, чем просто среднее значение (среднее), вы можете проверить статистику scipy

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

Для того, чтобы использовать reduceдля получения скользящего среднего, вам нужно отследить общее количество, а также общее количество элементов, видимых до сих пор. поскольку это не тривиальный элемент в списке, вам также нужно будет передать reduceдополнительный аргумент, чтобы сложить его.

>>> 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
интересно, но это не то, что он просил.
Йохан Лундберг

3

Оба могут дать вам близкие к аналогичным значениям по целому или по крайней мере 10 десятичных значений. Но если вы действительно рассматриваете длинные плавающие значения, оба могут быть разными. Подход может варьироваться в зависимости от того, чего вы хотите достичь.

>>> 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

Плавающие значения

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

@ Эндрю Кларк был прав в своем заявлении.


3

Предположим, что

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]]

Вы можете заметить, что xимеет размерность 3 * 10, если вам нужно получить в meanкаждой строке, вы можете напечатать это

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

не забудь 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
Неэффективное. Он преобразует все элементы в плавающее перед их добавлением. Это быстрее, чтобы преобразовать только длину.
Крис Костон

1

Найти среднее значение в списке, используя следующий код PYTHON :

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

попробуйте это легко.


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

или как опубликовано ранее

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

1.0 - убедиться, что вы получили деление с плавающей запятой


0

Комбинируя пару приведенных выше ответов, я пришел к следующему, которое работает с Reduce и не предполагает, что вы имеете Lдоступ к функции Reduction:

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

Я хочу добавить еще один подход

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)

Что делать, если пользователь добавляет числа с плавающей запятой в ваш массив? Результаты будут очень неточными.
Flame_Phoenix
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.