Spec-Zone.ru › NumPy 1.19

Что такое 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.

Вопросы о размере последовательности и скорости особенно важны в научных вычислениях. В качестве простого примера рассмотрим случай умножения каждого элемента в одномерной последовательности на соответствующий элемент в другой последовательности той же длины. Если данные хранятся в двух списках 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 могут быть многомерными массивами одинаковой формы, или скаляром и массивом, или даже двумя массивами с разными формами, при условии, что меньший массив «расширяем» до формы большего таким образом, что полученное широковещание является однозначным. Для подробных «правил» широковещательной передачи см. numpy.doc.broadcasting.

Кто еще использует NumPy?

NumPy полностью поддерживает объектно-ориентированный подход, начиная, еще раз, с ndarray. Например, ndarray — это класс, обладающий многочисленными методами и атрибутами. Многие его методы дублируются функциями в самом верхнем пространстве имен NumPy, позволяя программисту кодировать в любом предпочитаемом им парадигме. Эта гибкость позволила диалекту массивов NumPy и классу NumPy ndarray стать фактическим языком обмена многомерными данными, используемым в Python.

© 2005–2020 NumPy Developers
Licensed under the 3-clause BSD License.
https://numpy.org/doc/1.19/user/whatisnumpy.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API