Что такое NumPy?
NumPy — это фундаментальный пакет для научных вычислений в Python. Это библиотека Python, которая предоставляет многомерный массив, различные производные объекты (такие как маскированные массивы и матрицы) и множество процедур для быстрых операций над массивами, включая математические, логические, изменение формы, сортировку, выбор, ввод-вывод, дискретные преобразования Фурье, базовые операции линейной алгебры, базовые статистические операции, моделирование случайных величин и многое другое.
В основе пакета NumPy лежит объект ndarray. Он инкапсулирует n-мерные массивы однородных типов данных, при этом многие операции выполняются на скомпилированном коде для повышения производительности. Существуют несколько важных различий между массивами NumPy и стандартными последовательностями Python:
- Массивы NumPy имеют фиксированный размер при создании, в отличие от списков Python (которые могут динамически увеличиваться). Изменение размера
ndarrayприведет к созданию нового массива и удалению исходного. - Элементы в массиве NumPy должны быть одного типа данных, и, следовательно, будут иметь одинаковый размер в памяти. Исключение: можно иметь массивы объектов (Python, включая NumPy), тем самым позволяя иметь массивы с элементами разного размера.
- Массивы NumPy облегчают продвинутые математические и другие типы операций над большими объемами данных. Обычно такие операции выполняются более эффективно и с меньшим кодом, чем с помощью встроенных последовательностей Python.
- Все больше и больше научных и математических пакетов на основе Python используют массивы NumPy; хотя они обычно поддерживают ввод последовательностей Python, они преобразуют такой ввод в массивы NumPy перед обработкой, и они часто выводят массивы NumPy. Другими словами, для эффективного использования большей части (возможно, даже большей части) современной научной/математической программного обеспечения на основе Python недостаточно знать, как использовать встроенные типы последовательностей Python — также нужно знать, как использовать массивы NumPy.
Аспекты размера последовательности и скорости особенно важны в научных вычислениях. В качестве простого примера рассмотрим случай умножения каждого элемента последовательности 1-D на соответствующий элемент другой последовательности той же длины. Если данные хранятся в двух списках Python, a и b, мы можем перебирать каждый элемент:
c = []
for i in range(len(a)):
c.append(a[i]*b[i])
Это дает правильный ответ, но если a и b содержат миллионы чисел, мы заплатим за неэффективность циклов в Python. Мы можем выполнить ту же задачу намного быстрее на C, написав (для ясности мы пренебрегаем объявлениями переменных и инициализациями, выделением памяти и т. д.)
for (i = 0; i < rows; i++): {
c[i] = a[i]*b[i];
}
Это экономит все накладные расходы, связанные с интерпретацией кода Python и манипулированием объектами Python, но за счет преимуществ, полученных от кодирования на Python. Кроме того, объем работы по кодированию увеличивается с размерностью наших данных. Например, в случае двумерного массива код C (сокращенный, как и раньше) расширяется до
for (i = 0; i < rows; i++): {
for (j = 0; j < columns; j++): {
c[i][j] = a[i][j]*b[i][j];
}
}
NumPy дает нам лучшее из обоих миров: элементные операции являются «режим по умолчанию», когда вовлечен ndarray, но элементная операция быстро выполняется предварительно скомпилированным кодом C. В NumPy
c = a * b
выполняет то, что делали предыдущие примеры, со скоростью, близкой к C, но с простотой кода, которую мы ожидаем от чего-то, основанного на Python. Действительно, идиома NumPy еще проще! Этот последний пример иллюстрирует две функции NumPy, которые являются основой большей части его мощности: векторизация и трансляция.
Почему NumPy Быстрый?
Векторизация описывает отсутствие явных циклов, индексации и т. д. в коде — эти вещи, конечно, происходят «за кулисами» в оптимизированном, предварительно скомпилированном коде C. Векторизированный код имеет много преимуществ, среди которых:
- векторизированный код более лаконичен и легче читается
- меньше строк кода, как правило, означает меньше ошибок
- код больше соответствует стандартной математической записи (что упрощает, как правило, правильное кодирование математических конструкций)
- векторизация приводит к более «питоничному» коду. Без векторизации наш код был бы забит неэффективными и трудно читаемыми циклами
for.
Трансляция — это термин, используемый для описания неявного поэлементного поведения операций; в общем случае, в NumPy все операции, не только арифметические, но и логические, поразрядные, функциональные и т. д., ведут себя таким неявным поэлементным образом, т. е. они транслируются. Более того, в приведенном выше примере a и b могут быть многомерными массивами одной формы, или скаляром и массивом, или даже двумя массивами с разными формами, при условии, что меньший массив «расширяется» до формы большего массива таким образом, что результирующая трансляция однозначна. Более подробные «правила» трансляции см. в basics.broadcasting.
Кто еще использует NumPy?
NumPy полностью поддерживает объектно-ориентированный подход, начиная, еще раз, с ndarray. Например, ndarray — это класс, обладающий множеством методов и атрибутов. Многие из его методов дублируются функциями в внешнем пространстве имен NumPy, позволяя программисту кодировать в любом предпочитаемом парадигме. Эта гибкость позволила диалекту массивов NumPy и классу NumPy ndarray стать фактическим языком обмена многомерными данными, используемым в Python.
© 2005–2021 NumPy Developers
Licensed under the 3-clause BSD License.
https://numpy.org/doc/1.20/user/whatisnumpy.html