Как найти среднее в Python: популярные подходы и их особенности

Раздел: Коллекции -> Агрегация

Основные методы расчета среднего значения

Самый простой и рекомендуемый способ - использование функции mean() из модуля statistics.

Это решение подходит для любых итерируемых коллекций (списки, кортежи, множества) с числовыми элементами. Функция автоматически обрабатывает пустые последовательности, выбрасывая исключение StatisticsError.

import statistics

numbers = [12, 45, 78, 23, 56, 89, 34]
average = statistics.mean(numbers)
print(average)

Python максимальное значение (максимальное значение в python)

48.142857142857146

наименьшее значение python (наименьшее значение в python)

Цель использования: максимальная читаемость, минимум кода, встроенная обработка исключений. Подходит для однородных числовых последовательностей средней длины.

Типичные ошибки и проблемы:

  • Пустая коллекция - возникает statistics.StatisticsError. Решение: проверять длину перед вызовом или обрабатывать исключение.
  • Наличие нечисловых элементов (строк, None) - ошибка типа TypeError. Решение: предварительная фильтрация или преобразование.
  • Для больших массивов (более 10⁶ элементов) производительность уступает numpy.

Как вычислить среднее без импорта дополнительных модулей?

Простая формула: сумма элементов, делённая на количество.

def simple_mean(seq):
    if len(seq) == 0:
        return 0  # или raise ValueError
    return sum(seq) / len(seq)

print(simple_mean([10, 20, 30, 40, 50]))

среднее значение в python (среднее значение в python)

30.0

Когда это уместно: когда не хочется подключать внешние библиотеки или нужно полное понимание алгоритма. Однако для пустого списка результат неопределён (здесь возвращается 0).

Проблема: деление на ноль при пустом списке. Решение - явная проверка длины. Также при очень больших числах возможна потеря точности из-за арифметики с плавающей точкой.

Как посчитать среднее для больших числовых массивов?

Библиотека numpy предоставляет векторизованную операцию numpy.mean(), которая работает значительно быстрее для массивов от нескольких тысяч элементов.

import numpy as np

arr = np.array([1.5, 2.7, 3.2, 4.8, 5.1])
np_mean = np.mean(arr)
print(np_mean)
3.46

Случаи использования: научные расчёты, обработка изображений, работа с многомерными данными. numpy.mean() принимает аргумент axis для усреднения по заданной оси.

matrix = np.array([[1, 2], [3, 4], [5, 6]])
print(np.mean(matrix, axis=0))  # среднее по столбцам
print(np.mean(matrix, axis=1))  # среднее по строкам
[3. 4.]
[1.5 3.5 5.5]

Ошибка: передача списка, а не массива - numpy преобразует его автоматически, но это может вызвать неявное копирование. Проблема с NaN: np.mean() возвращает nan при наличии пропусков; используйте np.nanmean().

Как усреднить столбец датафрейма или Series?

Библиотека pandas предоставляет метод .mean() для объектов Series и DataFrame. Это удобно при анализе табличных данных.

import pandas as pd

data = {'product': ['A', 'B', 'C'], 'price': [100, 150, 200], 'quantity': [2, 3, 5]}
df = pd.DataFrame(data)
print(df['price'].mean())
print(df.mean(numeric_only=True))  # среднее по всем числовым столбцам
150.0
price      150.0
quantity     3.333333
dtype: float64

Когда применяется: работа с CSV, Excel, базами данных, группировка данных (groupby().mean()).

Проблема: по умолчанию df.mean() игнорирует нечисловые столбцы, но может выдать предупреждение. Явно указывайте numeric_only=True. Пропущенные значения (NaN) исключаются, что иногда нежелательно.

Можно ли получить среднее с помощью функционального подхода?

Использование reduce из functools для поэтапного накопления суммы - демонстрирует принцип агрегации, хотя на практике избыточно.

from functools import reduce

nums = [4, 8, 15, 16, 23, 42]
total = reduce(lambda acc, x: acc + x, nums, 0)
average = total / len(nums)
print(average)
18.0

Цель: обучение функциональному программированию, обработка потоков данных (с itertools). Для реальных задач лучше использовать встроенные функции.

Медленнее встроенного sum(). Ошибка: забыть начальное значение 0 - тогда первый элемент будет использован как аккумулятор, что приведёт к неверному результату при нечисловом первом элементе.

Как ускорить вычисление среднего для вещественных чисел?

Функция fmean() из модуля statistics (Python 3.8+) работает быстрее mean() за счёт внутреннего использования float и суммирования с повышенной точностью.

import statistics

values = [2.5, 3.6, 4.7, 5.8]
fast_avg = statistics.fmean(values)
print(fast_avg)
4.15

Применимость: когда все данные уже являются числами с плавающей точкой и требуется максимальная скорость в стандартной библиотеке.

Несовместимость со старыми версиями Python (до 3.8). При передаче целых чисел они неявно преобразуются в float, что может быть нежелательно, если нужна целочисленная точность.

Расширенные примеры вычисления среднего

1. Среднее с обработкой пустых последовательностей

Корректная обработка пустого списка - частая задача. Используем try-except с statistics.mean:

Пример
import statistics

def safe_mean(seq):
    try:
        return statistics.mean(seq)
    except statistics.StatisticsError:
        return None

print(safe_mean([]))
print(safe_mean([10, 20, 30]))
None
20.0

2. Среднее взвешенное (weighted average)

Для данных с разной значимостью:

Пример
def weighted_mean(values, weights):
    if len(values) != len(weights):
        raise ValueError("Длины списков не совпадают")
    total_weight = sum(weights)
    if total_weight == 0:
        return None
    return sum(v * w for v, w in zip(values, weights)) / total_weight

scores = [80, 90, 85]
weights = [0.2, 0.5, 0.3]
print(weighted_mean(scores, weights))
86.5

3. Среднее по сгруппированным данным с pandas

Агрегация по категориям - типичная задача для коллекций:

Пример
import pandas as pd

df = pd.DataFrame({
    'group': ['X', 'X', 'Y', 'Y', 'Z'],
    'value': [10, 20, 30, 40, 50]
})
print(df.groupby('group')['value'].mean())
group
X    15.0
Y    35.0
Z    50.0
Name: value, dtype: float64

4. Скользящее среднее (moving average) на чистом Python

Агрегация с окном - полезно для временных рядов:

Пример
def moving_average(data, window):
    if window > len(data):
        return []
    cumsum = [0]
    for i, x in enumerate(data, 1):
        cumsum.append(cumsum[i-1] + x)
    return [(cumsum[i] - cumsum[i-window]) / window for i in range(window, len(data)+1)]

series = [1, 2, 3, 4, 5, 6, 7]
print(moving_average(series, 3))
[2.0, 3.0, 4.0, 5.0, 6.0]

5. Среднее для вложенных списков (flatten then mean)

Если коллекция содержит подсписки, сначала нужно развернуть:

Пример
import itertools

nested = [[1, 2], [3, 4, 5], [6]]
flat = list(itertools.chain.from_iterable(nested))
average = sum(flat) / len(flat)
print(average)
3.5

6. Сравнение производительности для больших массивов

Генерация списка из 10⁷ элементов и замер времени:

Пример
import time
import statistics
import numpy as np

big_list = list(range(10_000_000))

start = time.time()
s1 = statistics.mean(big_list)
t1 = time.time() - start

start = time.time()
s2 = np.mean(big_list)
t2 = time.time() - start

print(f"statistics.mean: {s1:.2f}, time: {t1:.4f} сек")
print(f"numpy.mean:     {s2:.2f}, time: {t2:.4f} сек")
statistics.mean: 4999999.50, time: 1.2456 сек
numpy.mean:     4999999.50, time: 0.0891 сек

7. Работа с пропущенными значениями (NaN)

Использование np.nanmean для игнорирования NaN:

Пример
import numpy as np

arr = np.array([1.0, 2.0, np.nan, 4.0, np.nan])
print(np.nanmean(arr))
2.333333333333333

Среднее значение в Python - comments

En
среднее значение в python (python)