Нахождение среднего значения списка
Вопрос: Как мне найти арифметическое среднее для списка в Python? Например:
[1, 2, 3, 4] ⟶ 2.5
Я пытаюсь рассчитать среднее значение для списка чисел, но не знаю, как это сделать правильно. Можете ли вы, пожалуйста, помочь с примерами кода или объяснением?
5 ответ(ов)
Для того чтобы вычислить среднее значение элементов в списке xs
, вы можете использовать следующий код на Python:
xs = [15, 18, 2, 36, 12, 78, 5, 6, 9]
average = sum(xs) / len(xs)
В этом коде sum(xs)
вычисляет сумму всех элементов в списке, а len(xs)
возвращает количество элементов в списке. Делая деление sum(xs) / len(xs)
, вы получаете среднее арифметическое значений в списке xs
.
Помните, что если список пустой (то есть, len(xs)
равен 0), это вызовет ZeroDivisionError
. Поэтому полезно добавить проверку, чтобы избежать этой ошибки:
if len(xs) > 0:
average = sum(xs) / len(xs)
else:
average = 0 # или любое другое значение по вашему выбору
Таким образом, вы вычислите среднее значение безопасно.
Использование функции reduce()
для вычисления среднего значения списка может показаться избыточным, когда в Python уже есть функция sum()
, которая делает именно это. Тем не менее, есть несколько причин, по которым вы могли бы предпочесть reduce()
в некоторых ситуациях:
Гибкость:
reduce()
позволяет вам применить более сложные операции, которые могут комбинировать элементы списка несколькими способами. Например, вы можете рассчитывать взвешенное среднее или производить другие агрегирующие операции в одном месте.Читаемость: В специфичных случаях использование
reduce()
может сделать код более понятным для тех, кто привык к функциональному стилю программирования. Однако это довольно субъективно.Обучение концепциям функционального программирования: Если вы стремитесь изучить или научить других концепции функционального программирования, использование
reduce()
может быть хорошей практикой для демонстрации этого подхода.
Тем не менее, если ваша единственная цель — вычисление среднего, и нет дополнительных требований к вычислениям, то функция sum()
в сочетании с len()
— это самый простой и читаемый способ:
average = sum(l) / float(len(l))
Так что если ваша задача заключается только в нахождении среднего, использование sum()
действительно будет более оптимальным решением.
Если вы используете Python версии 3.4 или выше, у вас есть библиотека для работы со статистикой.
Вы можете ознакомиться с документацией по этой ссылке: https://docs.python.org/3/library/statistics.html
Для вычисления среднего арифметического вы можете использовать метод mean
. Предположим, у вас есть список чисел, для которых вы хотите найти среднее значение:
my_list = [11, 13, 12, 15, 17]
import statistics as s
s.mean(my_list)
Кроме того, в этой библиотеке есть и другие полезные методы, такие как stdev
(стандартное отклонение), variance
(дисперсия), mode
(мода), harmonic mean
(гармоническое среднее), median
(медиана) и др.
Редактировать:
Я добавил два других способа вычисления среднего значения списка (они актуальны только для Python 3.8 и выше). Вот сравнительный анализ, который я провел:
import timeit
import statistics
import numpy as np
from functools import reduce
import pandas as pd
import math
LIST_RANGE = 10
NUMBERS_OF_TIMES_TO_TEST = 10000
l = list(range(LIST_RANGE))
def mean1():
return statistics.mean(l)
def mean2():
return sum(l) / len(l)
def mean3():
return np.mean(l)
def mean4():
return np.array(l).mean()
def mean5():
return reduce(lambda x, y: x + y / float(len(l)), l, 0)
def mean6():
return pd.Series(l).mean()
def mean7():
return statistics.fmean(l)
def mean8():
return math.fsum(l) / len(l)
for func in [mean1, mean2, mean3, mean4, mean5, mean6, mean7, mean8]:
print(f"{func.__name__} took: ", timeit.timeit(stmt=func, number=NUMBERS_OF_TIMES_TO_TEST))
Вот результаты, которые я получил:
mean1 took: 0.09751558300000002
mean2 took: 0.005496791999999973
mean3 took: 0.07754683299999998
mean4 took: 0.055743208000000044
mean5 took: 0.018134082999999968
mean6 took: 0.6663848750000001
mean7 took: 0.004305374999999945
mean8 took: 0.003203333000000086
Интересно! Похоже, что math.fsum(l) / len(l)
является самым быстрым способом, затем идет statistics.fmean(l)
, и только потом sum(l) / len(l)
. Отлично!
Спасибо @Asclepius за то, что показал мне эти два других способа!
СТАРЫЙ ОТВЕТ:
С точки зрения эффективности и скорости, вот результаты, которые я получил, тестируя другие ответы:
# тест вычисления среднего значения
import timeit
import statistics
import numpy as np
from functools import reduce
import pandas as pd
LIST_RANGE = 10
NUMBERS_OF_TIMES_TO_TEST = 10000
l = list(range(LIST_RANGE))
def mean1():
return statistics.mean(l)
def mean2():
return sum(l) / len(l)
def mean3():
return np.mean(l)
def mean4():
return np.array(l).mean()
def mean5():
return reduce(lambda x, y: x + y / float(len(l)), l, 0)
def mean6():
return pd.Series(l).mean()
for func in [mean1, mean2, mean3, mean4, mean5, mean6]:
print(f"{func.__name__} took: ", timeit.timeit(stmt=func, number=NUMBERS_OF_TIMES_TO_TEST))
и результаты:
mean1 took: 0.17030245899968577
mean2 took: 0.002183011999932205
mean3 took: 0.09744236000005913
mean4 took: 0.07070840100004716
mean5 took: 0.022754742999950395
mean6 took: 1.6689282460001778
Таким образом, очевидный победитель — это:
sum(l) / len(l)
Вместо приведения к типу float
можно просто добавить 0.0
к сумме:
def avg(l):
return sum(l, 0.0) / len(l)
Такой подход гарантирует, что результат будет в формате числа с плавающей запятой, даже если все элементы входного списка являются целыми числами.
Как получить последний элемент списка?
Как клонировать список, чтобы он не изменялся неожиданно после присваивания?
Диапазон букв в Python
Вывод списка в обратном порядке с помощью функции range()
Почему statistics.mean() работает так медленно?