Нахождение среднего значения списка
Вопрос: Как мне найти арифметическое среднее для списка в 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)
Такой подход гарантирует, что результат будет в формате числа с плавающей запятой, даже если все элементы входного списка являются целыми числами.
Как получить последний элемент списка?
Как клонировать список, чтобы он не изменялся неожиданно после присваивания?
Самый быстрый способ проверить наличие значения в списке
Сравнение: генераторы списков против lambda + filter
Преобразование всех строк в списке в целые числа