Как вычислить стандартное отклонение с помощью 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 (количество элементов), а затем извлекается квадратный корень.
Краткий обзор ключевых параметров
| Параметр | Тип | По умолчанию | Назначение |
|---|---|---|---|
a | array_like | Обязательный | Входные данные |
axis | None, int или tuple | None | Ось/оси для вычисления |
dtype | dtype | None | Тип выходных данных |
ddof | int или float | 0 | Дельта степеней свободы |
keepdims | bool | False | Сохранить уменьшенные измерения |
where | array_like of bool | Включить все | Элементы для включения |
mean | array_like | Вычисляется | Предварительно вычисленное среднее |
correction | int или 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. Включает синтаксис, примеры и обработку ошибок.