Как вычислить стандартное отклонение с помощью NumPy: полное руководство по numpy.std()

Узнайте, как вычислить стандартное отклонение в NumPy, с практическими примерами, объяснением параметров и советами по производительности для анализа данных.

Что такое стандартное отклонение и почему это важно?

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

Независимо от того, анализируете ли вы показания датчиков, финансовые данные или признаки машинного обучения, понимание разброса данных крайне важно. Низкое стандартное отклонение означает, что значения плотно сгруппированы вокруг среднего, тогда как высокое стандартное отклонение сигнализирует о широком разбросе. Функция numpy.std() делает вычисление этой метрики лёгким и непринуждённым, даже для массивных многомерных массивов.

Начало работы с numpy.std() — основы

Функция numpy.std() вычисляет стандартное отклонение элементов массива вдоль указанной оси. По умолчанию она сглаживает массив и возвращает одно скалярное значение, представляющее общий разброс.

Вот базовый синтаксис:

numpy.std(a, axis=None, dtype=None, out=None, ddof=0, keepdims=<no value>, *, where=<no value>, mean=<no value>, correction=<no value>)

Разберём простой пример:

import numpy as np

data = np.array([10, 20, 30, 40, 50])
result = np.std(data)
print(result)  # Output: 14.142135623730951

Здесь вычисляется стандартное отклонение генеральной совокупности для сглаженного массива. Вычисление следует формуле, где сумма квадратов отклонений от среднего делится на N (количество элементов), а затем извлекается квадратный корень.

Краткий обзор ключевых параметров

ПараметрТипПо умолчаниюНазначение
aarray_likeОбязательныйВходные данные
axisNone, int или tupleNoneОсь/оси для вычисления
dtypedtypeNoneТип выходных данных
ddofint или float0Дельта степеней свободы
keepdimsboolFalseСохранить уменьшенные измерения
wherearray_like of boolВключить всеЭлементы для включения
meanarray_likeВычисляетсяПредварительно вычисленное среднее
correctionint или floatИмя параметра в Array API для ddof

Понимание параметра ddof: стандартное отклонение генеральной совокупности и выборки

Одно из самых важных различий в статистике — и частая причина путаницы — это разница между стандартным отклонением генеральной совокупности и выборки. Параметр ddof в numpy.std() управляет этим поведением.

Когда ddof=0 (по умолчанию), NumPy делит на N, давая стандартное отклонение генеральной совокупности. Это означает, что ваши данные рассматриваются как полный набор наблюдений.

Когда ddof=1, NumPy делит на N-1, давая стандартное отклонение выборки. Это известно как поправка Бесселя, и она обеспечивает несмещённую оценку дисперсии генеральной совокупности, когда ваши данные представляют собой случайную выборку.

import numpy as np

sample = np.array([2, 4, 4, 4, 5, 5, 7, 9])

# Стандартное отклонение генеральной совокупности (ddof=0)
pop_std = np.std(sample)  # 2.0

# Стандартное отклонение выборки (ddof=1)
sample_std = np.std(sample, ddof=1)  # 2.138...

Генеральная совокупность или выборка: когда что использовать

СценарийЗначение ddofПример использования
Известна вся генеральная совокупность0Данные переписи, полные журналы датчиков
Случайная выборка из большей совокупности1Результаты опросов, экспериментальные измерения
Большие наборы данных (N > 1000)0 или 1Разница становится незначительной

Согласно отчётам сообщества, многие специалисты по данным по умолчанию используют ddof=1 при работе с реальными наборами данных, поскольку большинство наборов данных являются выборками, а не полными генеральными совокупностями. Однако для очень больших массивов разница между двумя подходами практически незначительна.

Вычисление стандартного отклонения вдоль определённых осей

При работе с многомерными массивами часто требуется вычислить стандартное отклонение вдоль определённой оси. Параметр axis делает это простым и понятным.

import numpy as np

matrix = np.array([[1, 2, 3],
                   [4, 5, 6],
                   [7, 8, 9]])

# Стандартное отклонение всей матрицы
print(np.std(matrix))  # 2.581988897471611

# Вдоль строк (axis=0) — результат имеет форму (3,)
print(np.std(matrix, axis=0))  # [2.449, 2.449, 2.449]

# Вдоль столбцов (axis=1) — результат имеет форму (3,)
print(np.std(matrix, axis=1))  # [0.816, 0.816, 0.816]

Вы также можете передать кортеж целых чисел для вычисления стандартного отклонения сразу по нескольким осям:

tensor = np.random.rand(3, 4, 5)
result = np.std(tensor, axis=(0, 2))  # Форма: (4,)

Сводка поведения параметра axis

Форма массиваФорма результата при axis=0Форма результата при axis=1Результат при axis=None
(3, 4)(4,)(3,)скаляр
(2, 3, 4)(3, 4)(2, 4)скаляр
(5,)скалярОшибкаскаляр

Повышение точности и производительности с помощью параметров dtype и mean

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

Рассмотрим этот пример из документации NumPy:

a = np.zeros((2, 512*512), dtype=np.float32)
a[0, :] = 1.0
a[1, :] = 0.1

# Неточно с float32
print(np.std(a))         # 0.45000005

# Точно с float64
print(np.std(a, dtype=np.float64))  # 0.44999999925494177

Указание dtype=np.float64 заставляет NumPy использовать арифметику более высокой точности во время вычисления, что кардинально улучшает точность для больших массивов.

Оптимизация производительности с помощью параметра mean

Если вы уже вычислили среднее значение вашего массива, вы можете передать его через параметр mean, чтобы избежать избыточных вычислений. Это может значительно сэкономить время на больших наборах данных:

mean = np.mean(a, axis=1, keepdims=True)
std = np.std(a, axis=1, mean=mean)

Тесты производительности показывают, что этот подход может сократить время выполнения примерно на 30% по сравнению с внутренним вычислением среднего. Аргумент mean должен иметь форму, которую он имел бы при keepdims=True, и использовать ту же ось, что и вызов std().

Советы по точности и производительности

ПроблемаРешениеЭффект
Потеря точности float32Установить dtype=np.float64Более высокая точность
Повторное вычисление среднегоПередать предварительно вычисленный mean~30% быстрее
Ограничения памятиИспользовать параметр outИзбегает выделения памяти
Проблемы с трансляциейУстановить keepdims=TrueПравильная форма

Продвинутое использование: фильтрация элементов с помощью параметра where

Параметр where (доступен начиная с NumPy 1.20) позволяет выборочно включать элементы в вычисление стандартного отклонения с помощью булевой маски. Это невероятно полезно, когда вы хотите исключить выбросы или сосредоточиться на определённых подмножествах.

a = np.array([[14, 8, 11, 10],
              [7, 9, 10, 11],
              [10, 15, 5, 10]])

# Стандартное отклонение всех элементов
print(np.std(a))  # 2.614...

# Исключить третью строку
mask = [[True], [True], [False]]
print(np.std(a, where=mask))  # 2.0

Элементы, для которых маска равна False, просто игнорируются при вычислении. Это более эффективно с точки зрения памяти, чем создание отфильтрованной копии массива, особенно для больших наборов данных.

Собираем всё вместе: практический пример

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

import numpy as np

# Данные о температуре: 5 датчиков, 24 почасовых показания
np.random.seed(42)
temps = np.random.normal(loc=72, scale=5, size=(5, 24))

# Общий разброс по всем датчикам и часам
overall_std = np.std(temps, dtype=np.float64)

# Изменчивость по каждому датчику (по часам)
sensor_std = np.std(temps, axis=1, ddof=1)

# Изменчивость по часам между датчиками
hourly_std = np.std(temps, axis=0, ddof=1)

# Учитывать только показания выше 65°F
valid_temps_std = np.std(temps, where=temps > 65)

Именно такой многоугольный анализ демонстрирует все возможности numpy.std(). Вы можете быстро разрезать свои данные в разных измерениях и понять изменчивость на каждом уровне.

Часто задаваемые вопросы

В чём разница между numpy.std() и pandas std()?

Ключевое отличие заключается в значении ddof по умолчанию. Функция NumPy numpy.std() по умолчанию использует ddof=0 (стандартное отклонение генеральной совокупности), в то время как DataFrame.std() в pandas по умолчанию использует ddof=1 (стандартное отклонение выборки). Это означает, что две функции вернут разные значения для одних и тех же данных, если вы явно не зададите параметр ddof. При вычислении стандартного отклонения в стиле numpy всегда проверяйте, нужны ли вам статистики генеральной совокупности или выборки.

Как вычислить стандартное отклонение в стиле numpy для двумерного массива по столбцам?

Используйте axis=0 для вычисления вдоль столбцов. Для двумерного массива формы (строки, столбцы) np.std(arr, axis=0) вернёт массив формы (столбцы,), где каждый элемент — это стандартное отклонение соответствующего столбца. Установите ddof=1, если ваши данные представляют собой выборку, а не полную генеральную совокупность.

Почему numpy.std() даёт разные результаты для float32 и float64?

Float32 имеет только около 7 десятичных цифр точности, тогда как float64 — около 16. При суммировании квадратов отклонений по тысячам элементов float32 накапливает ошибки округления, которые искажают результат. Для точных вычислений стандартного отклонения в numpy на данных float32 всегда передавайте dtype=np.float64, чтобы принудительно использовать промежуточную арифметику более высокой точности.

Можно ли использовать numpy.std() с маскированными или пропущенными значениями?

Параметр where позволяет исключить определённые элементы, но для значений NaN лучше использовать numpy.nanstd(). Он автоматически игнорирует записи NaN и является стандартным подходом, когда ваш набор данных содержит пропущенные значения, которые нужно пропустить при вычислении стандартного отклонения в numpy.

Для полной документации по всем параметрам и граничным случаям обратитесь к официальному справочнику NumPy для numpy.std().

Связанные руководства

Как вычислить стандартное отклонение в Excel: полное руководство по функции СТАНДОТКЛОН

Узнайте, как вычислить стандартное отклонение в Excel с помощью функций СТАНДОТКЛОН, СТАНДОТКЛОН.Г и СТАНДОТКЛОН.В. Включает синтаксис, примеры и практические советы.

Как создать график стандартного отклонения в Excel: пошаговое руководство

Научитесь создавать график стандартного отклонения в Excel с помощью этого подробного руководства. Освойте колоколообразные кривые, функцию NORM.DIST и форматирование диаграмм.

Как читать и создавать график стандартного отклонения: полное руководство

Узнайте, как интерпретировать, строить и анализировать график стандартного отклонения, с пошаговыми инструкциями, реальными примерами и практическими советами.

Стандартное отклонение в Python: как его вычислить с примерами кода

Узнайте, как вычислить функцию стандартного отклонения в Python с помощью модуля statistics. Включает синтаксис, примеры и обработку ошибок.