Самоучитель по Python NumPy

Вы изучили основы языка Python и ищете более мощный способ анализа данных? NumPy — это то, что вам нужно. NumPy — это модуль для Python, который позволяет работать с многомерными массивами и матрицами. Он идеально подходит для научных и математических расчетов, поскольку отличается быстротой и эффективностью. Кроме того, NumPy поддерживает обработку сигналов и операции линейной алгебры. Так что если вам необходимо выполнять какие-либо математические операции с данными, то NumPy — это, скорее всего, библиотека для вас.

В этом учебном пособии мы покажем вам, как использовать NumPy в полной мере. Вы узнаете больше о массивах, а также научитесь работать с ними с помощью математических функций.

NumPy (что означает Numerical Python) — это библиотека, состоящая из объектов многомерных массивов и набора процедур для обработки этих массивов. С помощью NumPy можно выполнять математические и логические операции над массивами. В этом учебном пособии мы расскажем о том, что такое NumPy в Python, о типах данных в NumPy и многом другом.

Хотите скачать книги по Python в 2 клика? Тогда вам в наш телеграм канал PythonBooks 

Содержание

Что такое NumPy?

NumPy (расшифровывается как Numerical Python) — это библиотека для работы с массивами, созданная в 2005 году Трэвисом Олифантом. Она имеет функции для работы в области преобразования Фурье, линейной алгебры и матриц. Python NumPy — это проект с открытым исходным кодом, который можно использовать свободно.

Как установить NumPy Python?

Установка библиотеки NumPy — несложный процесс. Для этого можно использовать программу pip. Перейдите в командную строку и введите следующее:

pip install numpy 
If you are using Anaconda distribution, then you can use conda to install NumPy. conda install numpy 
Once the installation is complete, you can verify it by importing the NumPy library in the python interpreter. One can use the numpy library by importing it as shown below. 
import numpy 
If the import is successful, then you will see the following output. 
>>> import numpy 
>>> numpy.__version__ 
'1.17.2' 

От редакции Pythonist: об установке пакетов в Python читайте в статьях «Установка пакетов Python при помощи PIP» и «Как вручную установить пакет в Python».

Создание массивов NumPy

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

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

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

После создания массива NumPy им можно манипулировать различными способами. Например, можно изменять форму массива или индексировать массив для доступа к его элементам. Кроме того, с массивами NumPy можно выполнять математические операции, такие как сложение, умножение и деление.

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

Для начала необходимо импортировать библиотеку в программу. В модуле NumPy имеется функция array, которая создает массив.

Создание массива:

import numpy as np 
arr = np.array([1, 2, 3, 4, 5]) 
print(arr) 

# Вывод:
# [1 2 3 4 5]

Для создания массива в функцию array также можно передать кортеж:

import numpy as np 
arr = np.array((1, 2, 3, 4, 5)) 
print(arr)

# Вывод:
# [1 2 3 4 5]

Размерные массивы

0-мерные массивы

Следующий код создаст нульмерный массив со значением 36.

import numpy as np 
arr = np.array(36) 
print(arr) 

# Вывод:
# 36

Одномерный массив

Массив, элементами которого являются нульмерные массивы, является одномерным или 1-D массивом.

Приведенный ниже код создает одномерный массив.

import numpy as np 
arr = np.array([1, 2, 3, 4, 5]) 
print(arr) 

# Вывод:
# [1 2 3 4 5]

Двумерные массивы

Двумерные массивы — это массивы, элементами которых являются одномерные массивы. Следующий код создаст двумерный массив, значениями которого будут 1, 2, 3 и 4, 5, 6.

import numpy as np 
3
arr1 = np.array([[1, 2, 3], [4, 5, 6]]) 
print(arr1) 

# Вывод:
# [[1 2 3] 
# [4 5 6]]

Трехмерные массивы

Рассмотрим пример создания трехмерного массива из двух двумерных массивов:

import numpy as np 
arr1 = np.array([[[1, 2, 3], [4, 5, 6]], [[1, 2, 3], [4, 5, 6]]]) print(arr1) 

# Вывод:
# [[[1 2 3] 
# [4 5 6]] 
# [[1 2 3] 
# [4 5 6]]] 

Для определения размерности массива можно использовать ndim:

import numpy as np 
a = np.array(36) 
d = np.array([[[1, 2, 3], [4, 5, 6]], [[1, 2, 3], [4, 5, 6]]]) 
print(a.ndim) 
print(d.ndim) 

# Вывод:
# 0
# 3

Операции с использованием NumPy

Используя NumPy, разработчик может выполнять:

  • Математические и логические операции над массивами
  • Преобразования Фурье и процедуры для работы с формами
  • Операции, связанные с линейной алгеброй. NumPy имеет встроенные функции для линейной алгебры и генерации случайных чисел.

NumPy — замена MatLab

NumPy часто используется вместе с такими пакетами, как SciPy (Scientific Python) и Matplotlib (библиотека для построения графиков). Эта комбинация широко применяется в качестве замены MatLab, популярной платформы для технических вычислений.

ndarray

Наиболее важным объектом, определенным в NumPy, является N-мерный тип массива, называемый ndarray. Он описывает коллекцию элементов одного типа. Доступ к элементам коллекции осуществляется с помощью индекса.

Каждый элемент массива ndarray занимает тот же размер, что и блок в памяти. Каждый элемент ndarray представляет собой объект типа data (называемый dtype).

Экземпляр класса ndarray может быть создан с помощью различных методов создания массивов (их мы еще рассмотрим). Базовый ndarray создается с использованием функции array в NumPy следующим образом: numpy.array().

Это создает ndarray из любого объекта с реализацией интерфейса массива или из любого метода, возвращающего массив.

numpy.array(object, dtype = None, copy = True, order = None, subok = False, ndmin = 0)

Объект ndarray представляет собой непрерывный одномерный сегмент памяти компьютера, объединенный со схемой индексации, которая сопоставляет каждому элементу место в блоке памяти.

В блоке памяти элементы располагаются в основном порядке строк (стиль C) или в основном порядке столбцов (стиль FORTRAN или MatLab).

Приведенный выше конструктор принимает следующие параметры:

ПараметрОписание
objectЛюбой объект, экспонирующий метод интерфейса массива, возвращает массив или любую (вложенную) последовательность.
dtypeЖелаемый тип данных массива.
copyОпциональное копирование. По умолчанию (true), объект копируется.
orderC (по строкам) или F (по столбцам) или A (любой) (по умолчанию).
subokПо умолчанию возвращаемый массив принудительно преобразуется в базовый класс массива. Если true, допускаются подклассы.
ndminЗадает минимальное количество измерений результирующего массива.

Для лучшего понимания рассмотрим примеры.

Пример 1

Live Demo

import numpy as np 
a = np.array([1,2,3]) 
print a

# Вывод:
# [1, 2, 3]

Пример 2

Live Demo

# more than one dimensions 
import numpy as np 
a = np.array([[1, 2], [3, 4]]) 
print a

# Вывод:
# [[1, 2]
# [3, 4]]

Пример 3

Live Demo

# minimum dimensions 
import numpy as np 
a = np.array([1, 2, 3,4,5], ndmin = 2) 
print a

# Вывод:
# [[1, 2, 3, 4, 5]]

Пример 4

Live Demo

# dtype parameter 
import numpy as np 
a = np.array([1, 2, 3], dtype = complex) 
print a

# Вывод:
# [ 1.+0.j, 2.+0.j, 3.+0.j]

Типы данных в NumPy

Здесь приведен список различных типов данных в NumPy:

  1. bool_ — булев тип данных (True или False), значение, хранящееся в виде байта
  2. int_ — целочисленный тип по умолчанию (такой же, как long в C; обычно либо int64, либо int32)
  3. intc — идентичен C int (обычно int32 или int64)
  4. intp — целое число, используемое для индексации (аналогично C ssize_t; обычно int32 или int64)
  5. int8 — байт (от -128 до 127)
  6. int16 — целое число (от -32768 до 32767)
  7. float_ — сокращение для float64
  8. float64 — плавающее число двойной точности: знаковый бит, экспонента 11 бит, мантисса 52 бита
  9. complex_ — сокращение для complex128
  10. complex64 — комплексное число, представленное двумя 32-битными числами с плавающей запятой (вещественная и мнимая компоненты)
  11. complex128 — комплексное число, представленное двумя 64-битными числами с плавающей запятой (действительная и мнимая составляющие).

Числовые типы NumPy — это экземпляры объектов dtype (data-type), каждый из которых обладает уникальными характеристиками. Типы dtypes доступны в виде np.bool_, np.float32 и т.д.

Объекты типа данных (dtype)

Объект типа данных описывает интерпретацию фиксированного блока памяти, соответствующего массиву, в зависимости от следующих аспектов:

  • Тип данных (целое число, число с плавающей запятой или объект Python)
  • Размер данных
  • Порядок следования байтов (little-endian или big-endian).
  • В случае структурированного типа — имена полей, тип данных каждого поля и часть блока памяти, занимаемая каждым полем
  • Если тип данных является подмассивом, то его форма и тип данных.

Порядок следования байтов определяется префиксом ‘<‘ или ‘>’ к типу данных. ‘<‘ означает, что кодировка является little-endian (младший разряд хранится по наименьшему адресу). ‘>’ означает, что кодировка big-endian (старший байт хранится по наименьшему адресу).

Объект dtype строится с использованием следующего синтаксиса:

numpy.dtype(object, align, copy)

Он принимает следующие параметры:

  • object — преобразуемый в объект тип данных
  • align — если значение равно True, то добавляется выравнивание (padding) для поля, чтобы сделать его аналогичным C-структуре.
  • copy — создает новую копию объекта dtype. Если False, то результатом будет ссылка на встроенный объект типа данных

Пример 1

Live Demo

# using array-scalar type 
import numpy as np 
dt = np.dtype(np.int32) 
print dt

# Вывод:
# int32

Пример 2

Live Demo

#int8, int16, int32, int64 can be replaced by equivalent string 'i1', 'i2','i4', etc. 
import numpy as np 
dt = np.dtype('i4')
print dt 

# Вывод:
# int32

Пример 3

Live Demo

# using endian notation 
import numpy as np 
dt = np.dtype('>i4') 
print dt

# Вывод:
# >i4

В следующих примерах показано использование структурированного типа данных. Здесь необходимо объявить имя поля и соответствующий скалярный тип данных.

Пример 4

Live Demo

# first create structured data type 
import numpy as np 
dt = np.dtype([('age',np.int8)]) 
print dt

# Вывод:
# [('age', 'i1')]

Пример 5

Live Demo

# now apply it to ndarray object 
import numpy as np 
dt = np.dtype([('age',np.int8)]) 
a = np.array([(10,),(20,),(30,)], dtype = dt) 
print a

# Вывод:
# [(10,) (20,) (30,)]

Каждый встроенный тип данных имеет символьный код, который уникально идентифицирует его.

  • ‘b’ — булевый (логический) тип данных
  • ‘i’ — (знаковый) целочисленный тип данных
  • ‘u’ — беззнаковый целочисленный тип данных
  • ‘f’ — тип данных с плавающей запятой (вещественные числа)
  • ‘c’ — комплексный тип данных с плавающей запятой
  • ‘m’ — тип данных timedelta (разница между двумя моментами времени)
  • ‘M’ — тип данных datetime (дата и время)
  • ‘O’ — тип данных для объектов Python
  • ‘S’, ‘a’ — тип данных для байтовой строки (ASCII-строки)
  • ‘U’ — тип данных для строк Unicode
  • ‘V’ — тип данных для необработанных данных (пустой тип)

Давайте также рассмотрим различные атрибуты массивов в NumPy.

ndarray.shape

Этот атрибут массива возвращает кортеж, состоящий из размеров массива. Он также может быть использован для изменения размеров массива.

Пример 1

Live Demo

import numpy as np 
a = np.array([[1,2,3],[4,5,6]]) 
print a.shape

# Вывод:
# (2, 3)

Пример 2

Live Demo

# this resizes the ndarray 
import numpy as np 
a = np.array([[1,2,3],[4,5,6]]) 
a.shape = (3,2) 
print a 

# Вывод:
# [[1, 2][3, 4][5, 6]]

ndarray.ndim

Этот атрибут массива возвращает количество размерностей массива.

Пример 1

Live Demo

# an array of evenly spaced numbers 
import numpy as np 
a = np.arange(24) 
print a

# Вывод:
# [0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23]

Пример 2

Live Demo

# this is one dimensional array 
import numpy as np 
a = np.arange(24) 
a.ndim  
# now reshape it 
b = a.reshape(2,4,3) 
print b 
# b is having three dimensions

Выходные данные выглядят следующим образом:

[[[ 0,  1,  2] 
[ 3,  4,  5] 
[ 6,  7,  8] 
[ 9, 10, 11]]  
[[12, 13, 14] 
[15, 16, 17]
[18, 19, 20] 
[21, 22, 23]]] 

numpy.itemsize

Этот атрибут массива возвращает длину каждого элемента массива в байтах.

Пример 1

Live Demo

# dtype of array is int8 (1 byte) 
import numpy as np 
x = np.array([1,2,3,4,5], dtype = np.int8)
print x.itemsize

# Вывод:
# 1

Пример 2

Live Demo

# dtype of array is now float32 (4 bytes) 
import numpy as np 
x = np.array([1,2,3,4,5], dtype = np.float32) 
print x.itemsize

# Вывод:
# 4

numpy.flags

Объект ndarray имеет следующие атрибуты:

АтрибутОписание
C_CONTIGUOUS (C)Данные находятся в одном сегменте в стиле C (последовательно в памяти)
F_CONTIGUOUS (F)Данные находятся в одном сегменте в стиле Fortran (последовательно в памяти)
OWNDATA (O)Массив владеет своей памятью или заимствует ее у другого объекта
WRITEABLE (W)Область данных можно записывать. Установка этого значения в False блокирует данные, делая их доступными только для чтения
ALIGNED (A)Данные и все элементы выровнены соответствующим образом для аппаратного обеспечения
UPDATEIFCOPY (U)Этот массив является копией другого массива. При удалении этого массива базовый массив будет обновлен содержимым этого массива

Текущие значения атрибутов возвращаются функцией flags. В следующем примере показаны текущие значения флагов.

Live Demo

import numpy as np 
x = np.array([1,2,3,4,5]) 
print x.flags

Выходные данные выглядят следующим образом:

C_CONTIGUOUS : True 
F_CONTIGUOUS : True 
OWNDATA : True 
WRITEABLE : True 
ALIGNED : True 
UPDATEIFCOPY : False

Методы создания массивов NumPy

Новый объект ndarray может быть создан с помощью любой из следующих процедур создания массивов или с помощью низкоуровневого конструктора ndarray.

numpy.empty()

Создает неинициализированный массив заданной формы и dtype. Вот пример с параметрами:

numpy.empty(shape, dtype = float, order = 'C').

Функция принимает следующие параметры:

  • shape — форма пустого массива в виде целого числа или кортежа целых чисел
  • dtype — желаемый тип данных для выходного массива. Необязательный параметр
  • order — может иметь значение ‘C’ для массива в стиле C (по строкам) или ‘F’ для массива в стиле Fortran (по столбцам)

Пример

В следующем коде показан пример пустого массива.

Live Demo

import numpy as np 
x = np.empty([3,2], dtype = int) 
print x

# Вывод:
# [[22649312 1701344351] [1818321759 1885959276] [16779776 156368896]]

numpy.zeros

Возвращает новый массив заданного размера, заполненный нулями.

numpy.zeros(shape, dtype = float, order = 'C')

Конструктор принимает следующие параметры:

  • shape — форма пустого массива в виде целого числа или последовуательности целых чисел
  • dtype — желаемый тип данных для выходного массива. Необязательный параметр
  • order — может иметь значение ‘C’ для массива в стиле C (по строкам) или ‘F’ для массива в стиле Fortran (по столбцам)

Пример

Live Demo

# array of five ones. Default dtype is float 
import numpy as np 
x = np.ones(5) 
print x

# Вывод:
# [ 1. 1. 1. 1. 1.]

Индексы и срезы в NumPy

К содержимому объекта ndarray можно обратиться, а также изменить его при помощи индексов и срезов, подобно встроенным в Python объектам-контейнерам.

Как упоминалось ранее, элементы в объекте ndarray используют индексацию с нуля. Доступны три типа индексации: доступ к полям, базовые срезы и расширенная индексация.

Базовые срезы являются расширением основного концепта срезов в Python для n-мерных массивов. Объект среза Python создается путем передачи параметров start, stop и step встроенной функции slice. Этот объект среза передается массиву для извлечения части массива.

Пример 1

Live Demo

import numpy as np 
a = np.arange(10) 
s = slice(2,7,2) 
print a[s]

# Вывод:
# [2 4 6]

В приведенном выше примере объект ndarray создается с помощью функции arange(). Затем определяется объект среза с значениями start, stop и step равными 2, 7 и 2 соответственно. Когда этот объект среза передается в ndarray, из него извлекается часть, начиная с индекса 2 до 7 с шагом 2.

Тот же результат можно получить, передав параметры среза, разделенные двоеточием (start:stop:step), непосредственно в объект ndarray.

Пример 2

Live Demo

import numpy as np 
a = np.arange(10) 
b = a[2:7:2] 
print b

# Вывод:
# [2 4 6]

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

Пример 3

Live Demo

# slice single item 
import numpy as np 
a = np.arange(10) 
b = a[5] 
print b

# Вывод:
# 5

Пример 4

Live Demo

# slice items starting from index 
import NumPy as np 
a = np.arange(10) 
print a[2:]

# Вывод:
# [2 3 4 5 6 7 8 9]

Пример 5

Live Demo

# slice items between indexes 
import numpy as np 
a = np.arange(10) 
print a[2:5]

# Вывод:
# [2 3 4]

Приведенное выше описание применимо и к многомерному массиву ndarray.

Расширенное индексирование

Можно сделать выборку из ndarray, которая является некортежной последовательностью, объектом ndarray с типом данных integer или Boolean или кортежем, в котором хотя бы один элемент является последовательностью. Расширенная индексация всегда возвращает копию данных. В отличие от этого, срез представляет только вид (view) данных, а не создает копию.

Существует два типа расширенного индексирования: Integer и Boolean.

Целочисленное индексирование

Этот механизм помогает выбирать произвольный элемент массива на основе его N-мерного индекса. Каждый целочисленный массив представляет количество индексов в этом измерении. Когда индекс состоит из столько же целочисленных массивов, сколько измерений целевого ndarray, выбор становится простым и прямолинейным.

В приведенном ниже примере выбирается один элемент из указанного столбца каждой строки объекта ndarray. Таким образом, индекс строки содержит все номера строк, а индекс столбца указывает на элемент, который нужно выбрать.

Пример 1

import numpy as np 
x = np.array([[1, 2], [3, 4], [5, 6]]) 
y = x[[0,1,2], [0,1,0]] 
print y

# Вывод:
# [1 4 5]

В выборку попадают элементы по адресам (0,0), (1,1) и (2,0) из первого массива.

Расширенное и базовое индексирование можно комбинировать, используя один срез (:) или многоточие (…) с индексным массивом. В следующем примере для расширенного индекса столбца используется срез. Результат будет одинаковым, если использовать срез для обоих индексов. Однако расширенная индексация приводит к созданию копии и может иметь другую реализацию в памяти.

Булева индексация массива (Boolean Array Indexing)

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

Пример 1

В данном примере в результате булевого индексирования возвращаются элементы больше 5.

Live Demo

import numpy as np 
x = np.array([[ 0,  1,  2],[ 3,  4,  5],[ 6,  7,  8],[ 9, 10, 11]]) 
print 'Our array is:' 
print x 
print '\n'  
# Now we will print the items greater than 5 
print 'The items greater than 5 are:' 
print x[x > 5]

Выходные данные этой программы будут иметь следующий вид:

Our array is: 
[[ 0  1  2] 
 [ 3  4  5] 
 [ 6  7  8] 
 [ 9 10 11]] 

The items greater than 5 are:
[ 6  7  8  9 10 11] 

Broadcasting в NumPy

Термин «broadcasting» относится к возможности NumPy обрабатывать массивы разных форматов во время арифметических операций.

Арифметические операции над массивами обычно выполняются на соответствующих элементах. Если два массива имеют одинаковую форму, то эти операции выполняются без проблем.

Пример 1

import numpy as np 
a = np.array([1,2,3,4]) 
b = np.array([10,20,30,40]) 
c = a * b 
print c

# Вывод:
# [10 40 90 160]

Если размеры двух массивов не совпадают, то операции между элементами невозможны. Однако операции над массивами несхожей формы все же возможны в NumPy благодаря возможности трансляции. Меньший массив транслируется в размер большего массива, чтобы они имели совместимые формы.

Трансляция возможна, если выполняются следующие правила:

  • Массив с меньшим ndim получает в своей форме значение ‘1’.
  • Размер в каждом измерении выходной формы является максимальным из размеров входной формы в этом измерении.
  • Входные данные могут быть использованы в вычислениях, если их размер в определенном измерении совпадает с размером вывода или если их значение точно равно 1.
  • Если вход имеет размерность 1, то первая запись данных в этой размерности используется для всех вычислений по этой размерности.

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

  • Массивы имеют одинаковую форму.
  • Массивы имеют одинаковое количество измерений и длина каждого измерения равна либо общей длине, либо 1.
  • Массив, имеющий слишком мало измерений, может иметь форму, дополненную измерением длины 1, чтобы указанное выше свойство было истинным.

Итерирование по массиву в NumPy

Пакет NumPy содержит объект итератора numpy.nditer. Это эффективный многомерный объект итератора, с помощью которого можно выполнять итерацию по массиву. Каждый элемент массива посещается с использованием стандартного интерфейса итератора Python.

Создадим массив 3X4 с помощью функции arrange() и выполним итерацию по нему с помощью nditer.

import numpy as np

# Создаем массив 3x4 с помощью функции arange()
array = np.arange(12).reshape(3, 4)

# Выполняем итерацию по массиву с помощью nditer
for element in np.nditer(array):
    print(element, end=' ')

Итерация по массивам возможна с помощью цикла for.

Пример 1

import numpy as np 
arr1 = np.array([1, 2, 3]) 
for i in arr1: 
    print(i) 

# Вывод:
# 1
# 2
# 3

Пример 2

import numpy as np 
arr = np.array([[4, 5, 6], [1, 2, 3]]) 
for x in arr: 
    print(x) 

# Вывод:
# [4, 5, 6]
# [1, 2, 3]

Пример 3

import numpy as np 
array1 = np.array([[1, 2, 3], [4, 5, 6]]) 
for x in array1: 
    for y in x: 
        print(y) 

Вывод:

1
2
3
4
5
6

Манипуляции с массивами в NumPy

Для манипулирования элементами объекта ndarray в пакете NumPy имеется несколько процедур. Их можно разделить на следующие типы:

  • Изменение формы
  • Операции транспонирования
  • Изменение размеров
  • Объединение массивов
  • Разбиение массивов
  • Добавление/удаление элементов
  • Побитовые операции

Изменение формы:

Форма (Shape)Описание
reshapeДает новую форму массиву без изменения его данных
flat1-мерный итератор по массиву
flattenВозвращает копию массива, сплющенную в одну размерность
ravelВозвращает непрерывно сплющенный массив

Операции транспонирования:

Операция (Operation)Описание
transposeПереставляет размерности массива
ndarray.TТо же самое, что и self.transpose()
rollaxisСдвигает указанную ось назад
swapaxesОбменивает две оси массива

Изменение размеров:

Размерность (Dimension)Описание
broadcastСоздает объект, который имитирует трансляцию (broadcasting)
broadcast_toТранслирует массив в новую форму
expand_dimsРасширяет форму массива
squeezeУдаляет одномерные записи из формы массива

Объединение массивов:

Массив (Array)Описание
concatenateОбъединяет последовательность массивов вдоль существующей оси
stackОбъединяет последовательность массивов вдоль новой оси
hstackСоединяет массивы в последовательности горизонтально (по столбцам)
vstackСоединяет массивы в последовательности вертикально (по строкам)

Разбиение массивов:

Массив (Array)Описание
splitРазделяет массив на несколько подмассивов
hsplitРазделяет массив на несколько подмассивов горизонтально (по столбцам)
vsplitРазделяет массив на несколько подмассивов вертикально (по строкам)

Добавление/удаление элементов:

Элемент (Element)Описание
resizeВозвращает новый массив с указанной формой
appendДобавляет значения в конец массива
insertВставляет значения вдоль указанной оси перед указанными индексами
deleteВозвращает новый массив с удаленными подмассивами вдоль оси
uniqueНаходит уникальные элементы массива

Побитовые операции:

Операция (Operation)Описание
bitwise_andВыполняет побитовую операцию AND над элементами массива
bitwise_orВыполняет побитовую операцию OR над элементами массива
invertВыполняет побитовую операцию NOT (инвертирование) над элементами массива
right_shiftСдвигает биты двоичного представления чисел вправо

Давайте рассмотрим несколько примеров применения этих функций.

Переформирование массивов NumPy

Изменение формы массива — это изменение его размеров, с помощью которого можно добавлять или удалять элементы в каждом измерении.

Из одномерного в двумерный

Следующий код преобразует одномерный массив в двумерный массив. Результат будет содержать 3 массива, каждый из которых будет иметь 4 элемента.

import numpy as np 
array_1 = np.array([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]) 
newarr1 = array_1.reshape(3, 4) 
print(newarr1) 

# Вывод:
# [[ 1 2 3 4]
# [ 5 6 7 8]
# [ 9 10 11 12]]

Из одномерного в трехмерный

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

import numpy as np 
array_1= np.array([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]) 
newarr1 = array_1.reshape(2, 3, 2) 
print(newarr1)

Вывод:

[[[ 1 2] 
[ 3 4] 
[ 5 6]] 
[[ 7 8] 
[ 9 10] 
[11 12]]] 

Сглаживание

Преобразование массивов большей размерности в одномерные называется сглаживанием массивов.

import numpy as np 
arr1= np.array([[4,5,6], [7, 8, 9]]) 
newarr1 = arr1.reshape(-1) 
print(newarr1) 

# Вывод:
# [1 2 3 4 5 6] 

Объединение массивов в NumPy

Объединение — это операция, при которой один или два массива объединяются в один массив. В NumPy массивы объединяются вдоль осей. Для этой операции используется функция concatenate(), которая принимает последовательность массивов, которые нужно объединить.

Если параметр axis не указан, по умолчанию он принимает значение 0, что означает объединение массивов вдоль первой оси (строки).

import numpy as np 
arr1 = np.array([1, 2, 3]) 
arr2 = np.array([4, 5, 6]) 
finalarr = np.concatenate((arr1, arr2)) 
print(finalarr) 

# Вывод:
# [1 2 3 4 5 6]

Следующий код объединяет указанные массивы вдоль строк:

import numpy as np 
arr1 = np.array([[1, 2], [3, 4]]) 
arr2 = np.array([[5, 6], [7, 8]]) 
finalarr = np.concatenate((arr1, arr2), axis=1) 
print(finalarr) 

# Вывод:
# [[1 2 5 6] 
# [3 4 7 8]] 

Разбиение массива в NumPy

Как мы знаем, операция split делает обратное действие по сравнению с операцией join. Она разбивает один массив на несколько частей согласно указанным параметрам.

Для этой операции используется функция array_split(), которой необходимо передать количество разбиений вместе с массивом.

import numpy as np 
arr1 = np.array([7, 8, 3, 4, 1, 2]) 
finalarr = np.array_split(arr1, 3) 
print(finalarr) 

# Вывод:
# [array([7, 8]), array([3, 4]), array([1, 2])]

Рассмотрим исключительный случай, когда количество элементов меньше требуемого, и понаблюдаем за выводом:

import numpy as np 
array_1 = np.array([4, 5, 6,1,2,3]) 
finalarr = np.array_split(array_1, 4) 
print(finalarr) 

# Вывод:
# [array([4, 5]), array([6, 1]), array([2]), array([3])]

Разбиение на массивы

Функция array_split() вернет массив, содержащий подмассивы.

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

import numpy as np 
array1 = np.array([4, 5, 6,7,8,9]) 
finalarr = np.array_split(array1, 3) 
print(finalarr[0]) 

print(finalarr[1]) 

# Вывод:
# [4 5]
# [6 7]

Разбиение двумерных массивов происходит аналогично. Попробуйте передать двумерный массив в array_split().

import numpy as np 
arr1 = np.array([[1, 2], [3, 4], [5, 6], [7, 8], [9, 10], [11, 12]]) 
finalarr = np.array_split(arr1, 3) 
print(finalarr) 

Вывод:

[array([[1, 2], 
[3, 4]]), array([[5, 6], 
[7, 8]]), array([[ 9, 10], 
[11, 12]])] 

Поиск в массиве NumPy

Для поиска в массиве используется метод where(). Он возвращает индекс значения, переданного в метод.

Приведенный ниже код вернет кортеж, указывающий на то, что элемент 4 находится по адресам 3, 5 и 6

import numpy as np 
arr1 = np.array([1, 2, 3, 4, 5, 4, 4]) 
y = np.where(arr1 == 4) 
print(y)

# Вывод:
# (array([3, 5, 6]),)

Математические функции в NumPy

Вполне понятно, что NumPy содержит большое количество разнообразных математических операций. Библиотека предоставляет стандартные тригонометрические функции, функции для выполнения арифметических операций, работы с комплексными числами и т.д.

Тригонометрические функции

В NumPy имеются стандартные тригонометрические функции, которые возвращают тригонометрические коэффициенты для заданного угла в радианах.

Пример

Live Demo

import numpy as np 
a = np.array([0,30,45,60,90]) 
print 'Sine of different angles:' 
# Convert to radians by multiplying with pi/180 
print np.sin(a*np.pi/180) 
print '\n'  
print 'Cosine values for angles in array:' 
print np.cos(a*np.pi/180) 
print '\n'  
print 'Tangent values for given angles:' 
print np.tan(a*np.pi/180)

Вывод:

Sine of different angles:

[ 0.          0.5         0.70710678  0.8660254   1.        ]

Cosine values for angles in array:

[  1.00000000e+00   8.66025404e-01   7.07106781e-01   5.00000000e-01

6.12323400e-17]                                                            

Tangent values for given angles:

[  0.00000000e+00   5.77350269e-01   1.00000000e+00   1.73205081e+00

1.63312394e+16]

Функции arcsin, arcos и arctan возвращают тригонометрические обратные значения sin, cos и tan заданного угла. Результаты этих функций можно проверить с помощью функции numpy.degrees(), которая преобразует радианы в градусы.

Функции для округления

Функция numpy.around(a,decimals) возвращает значение, округленное до нужной точности. Функция принимает следующие параметры:

  • a — входные данные
  • decimals — количество десятичных знаков для округления. По умолчанию равно 0. Если отрицательное, целое число округляется до позиции слева от десятичной точки.

Статистические функции в NumPy

В NumPy имеется достаточно много полезных статистических функций, позволяющих находить минимум, максимум, процентиль, стандартное отклонение и дисперсию и т.д. по заданным элементам массива.

Например, функции numpy.amin() и numpy.amax() возвращают минимальное и максимальное значение из элементов заданного массива вдоль указанной оси.

Пример

Live Demo

import numpy as np 
a = np.array([[3,7,5],[8,4,3],[2,4,9]]) 
print 'Our array is:' 
print a  
print '\n'  
print 'Applying amin() function:' 
print np.amin(a,1) 
print '\n'  
print 'Applying amin() function again:' 
print np.amin(a,0) 
print '\n'  
print 'Applying amax() function:' 
print np.amax(a) 
print '\n’
print 'Applying amax() function again:' 
print np.amax(a, axis = 0)

В результате будет получен следующий вывод:

Our array is:
[[3 7 5]
[8 4 3]
[2 4 9]]

Applying amin() function:
[3 3 2]

Applying amin() function again:
[2 4 3]

Applying amax() function:
9

Applying amax() function again:
[8 7 9]

Функция numpy.ptp() возвращает диапазон (максимум-минимум) значений вдоль оси.

Live Demo

import numpy as np 
a = np.array([[3,7,5],[8,4,3],[2,4,9]]) 
print 'Our array is:' 
print a 
print '\n'  
print 'Applying ptp() function:' 
print np.ptp(a) 
print '\n'  
print 'Applying ptp() function along axis 1:' 
print np.ptp(a, axis = 1) 
print '\n'   
print 'Applying ptp() function along axis 0:'
print np.ptp(a, axis = 0) 
numpy.percentile()

Процентиль (англ. Percentile) — это значение, которое заданная случайная величина не превышает с фиксированной вероятностью, заданной в процентах.

Функция numpy.percentile() принимает следующие аргументы:

  • a — входной массив
  • q — процентиль, который нужно вычислить. Должен быть в диапазоне от 0 до 100
  • axis — ось, по которой будет вычисляться процентиль


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

В следующей таблице показано сравнение трех алгоритмов сортировки:

ВидСкоростьНаихудший случайРабочее пространствоСтабильность
‘quicksort’1O(n^2)0нет
‘mergesort’2O(n*log(n))~n/2да
‘heapsort’3O(n*log(n))0нет

Функция numpy.sort(a, axis, kind, order) возвращает отсортированную копию входного массива. Она имеет следующие параметры:

  • a — массив, который нужно отсортировать
  • axis — ось, по которой нужно произвести сортировку. Если значение None, массив сплющивается и сортируется по последней оси
  • kind — по умолчанию используется алгоритм quicksort
  • order — если массив содержит поля (структурированный массив), указывает порядок полей для сортировки

Свайп байтов в NumPy

Мы видели, что данные, хранящиеся в памяти компьютера, зависят от того, какую архитектуру использует процессор. Они могут быть little-endian (младший байт хранится по наименьшему адресу) или big-endian (старший байт хранится по наименьшему адресу).

Функция numpy.ndarray.byteswap() переключается между двумя представлениями: big-endian и little-endian.

Копии и представления массивов в NumPy

Разница между копией (copy) и представлением (view) массива в NumPy заключается в том, что представление является просто представлением исходного массива, в то время как копия является новым массивом.

Копия не влияет на исходный массив, и изменения, внесенные в копию, ограничены только новым созданным массивом. Множество изменений, внесенных в исходный массив, не будут отражены в копии. Однако в представлении изменения, внесенные в него, будут отражены в исходном массиве, и наоборот.

Давайте разберемся в этом на примерах.

Создание копии:

import numpy as np 
arr1 = np.array([1, 2, 3, 4, 5]) 
y = arr1.copy() 
arr1[0] = 36 
print(arr1) 
print(y) 

# Вывод:
# [42 2 3 4 5]
# [1 2 3 4 5]

Создание представления:

import numpy as np 
arr1 = np.array([1, 2, 3, 4, 5]) 
y= arr1.view() 
arr1[0] = 36 
print(arr1) 
print(y) 

# Вывод:
# [36 2 3 4 5] 
# [36 2 3 4 5]

Обратите внимание на вывод: изменения, внесенные в исходный массив, отражаются и в представлении.

Матричная библиотека

Пакет NumPy содержит матричную библиотеку numpy.matlib. В этом модуле есть функции, возвращающие матрицы вместо объектов ndarray.

matlib.empty()

Функция matlib.empty(shape, dtype, order) возвращает новую матрицу без инициализации записей. Функция принимает следующие параметры:

  • shape — целое число или кортеж целых чисел, определяющий форму новой матрицы,
  • dtype — тип данных выходной матрицы (необязательный параметр),
  • order — порядок данных (row-major или column-major, ‘C’ или ‘F’).

Пример

Live Demo

import numpy.matlib 
import numpy as np 
print np.matlib.empty((2,2)) 
# filled with random data

В результате будет получен следующий результат:

[[ 2.12199579e-314, 4.24399158e-314]
[ 4.24399158e-314, 2.12199579e-314]]

numpy.matlib.eye()

Функция numpy.matlib.eye(n, M,k, dtype) возвращает матрицу, в которой единицы расположены на главной диагонали, а в остальных местах нули. Функция принимает следующие параметры:

  • n — количество строк в результирующей матрице,
  • M — количество столбцов (по умолчанию равно n),
  • k — индекс диагонали,
  • dtype — тип данных выходной матрицы.

Пример

Live Demo

import numpy.matlib 
import numpy as np 
print np.matlib.eye(n = 3, M = 4, k = 0, dtype = float)

В результате будет получен следующий результат:

[[ 1. 0. 0. 0.]
[ 0. 1. 0. 0.]
[ 0. 0. 1. 0.]]

NumPy и построение графиков

Matplotlib — это библиотека построения графиков для Python. Она используется вместе с NumPy для создания среды, которая является эффективной опенсорсной альтернативой MatLab. Она также может использоваться с такими графическими инструментами, как PyQt и wxPython.

Модуль Matplotlib был впервые написан Джоном Д. Хантером. С 2012 года основным разработчиком является Майкл Дроттбум. В настоящее время Matplotlib 1.5.1 является стабильной версией. Пакет доступен как в бинарном дистрибутиве, так и в виде исходного кода на сайте www.matplotlib.org.

Традиционно пакет импортируется в Python-скрипт следующим образом:

from matplotlib import pyplot as plt

Здесь pyplot() — важнейшая функция библиотеки matplotlib, которая используется для построения двумерных данных. Следующий скрипт строит график уравнения y = 2x + 5

Пример:

import numpy as np 
from matplotlib import pyplot as plt 
x = np.arange(1,11) 
y = 2 * x + 5 
plt.title("Matplotlib demo") 
plt.xlabel("x axis caption") 
plt.ylabel("y axis caption") 
plt.plot(x,y) 
plt.show()

Объект ndarray x создается с помощью функции np.arange() для значений на оси x. Соответствующие значения на оси y хранятся в другом объекте ndarray y. Эти значения отображаются с использованием функции plot() из подмодуля pyplot пакета matplotlib.

Графическое представление выводится на экран с помощью функции show().

Вместо линейного графика значения можно отображать дискретно, добавив в функцию plot() строку форматирования.

numpy.histogram()

В NumPy имеется функция numpy.histogram(), с помощью которой можно получить графическое изображение частотного распределения данных. Прямоугольники равной горизонтальной ширины, соответствующие интервалам классов (бинам), имеют переменную высоту, соответствующую частоте.

Функция numpy.histogram() принимает в качестве параметров входной массив и бины. Последовательные элементы массива bin служат границами каждого столбца гистограммы.

Прим. переводчика: англ. «bin» применительно к гистограммам переводится как «столбец гистограммы».

import numpy as np 
a = np.array([22,87,5,43,56,73,55,54,11,20,51,5,79,31,27]) 
np.histogram(a,bins = [0,20,40,60,80,100]) 
hist,bins = np.histogram(a,bins = [0,20,40,60,80,100]) 
print hist 
print bins 

# Вывод:
# [3 4 5 2 1]
# [0 20 40 60 80 100]

plt()

Matplotlib может преобразовать это числовое представление гистограммы в график. Функция plt() подмодуля pyplot принимает в качестве параметров массив, содержащий данные, и массив bin и преобразует их в гистограмму.

from matplotlib import pyplot as plt 
import numpy as np  
a = np.array([22,87,5,43,56,73,55,54,11,20,51,5,79,31,27]) 
plt.hist(a, bins = [0,20,40,60,80,100]) 
plt.title("histogram") 
plt.show()

Ввод и вывод данных в NumPy

Объекты ndarray могут быть сохранены на диске или считаны с него. Доступны следующие функции ввода-вывода:

  • функции load() и save() работают с бинарными файлами numPy (с расширением npy)
  • функции loadtxt() и savetxt() работают с обычными текстовыми файлами.

В NumPy реализован простой формат файлов для объектов ndarray. В файле с расширением .npy хранятся данные, форма, dtype и другая информация, необходимая для реконструирования массива ndarray из памяти компьютера. Благодаря этому массив будет извлечен корректно, даже если файл находится на другой машине с другой архитектурой.

Функция numpy.save() сохраняет входной массив на вашем устройстве с расширением .npy.

import numpy as np 
a = np.array([1,2,3,4,5]) 
np.save('outfile',a)

Для восстановления массива из файла outfile.npy используйте функцию load().

import numpy as np 
b = np.load('outfile.npy') 
print b 

# Вывод:
# array([1, 2, 3, 4, 5])

Функции save() и load() принимают дополнительный булевый параметр allow_pickles. Pickles в Python используются для сериализации и де-сериализации объектов перед сохранением на диске или чтением из него.

Для хранения и извлечения данных массива в формате простого текстового файла используются функции savetxt() и loadtxt().

Пример

import numpy as np 
a = np.array([1,2,3,4,5]) 
np.savetxt('out.txt',a) 
b = np.loadtxt('out.txt') 
print b 

# Вывод:
# [ 1. 2. 3. 4. 5.]

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

1. Что такое NumPy и почему он используется в Python?

NumPy представляет собой библиотеку, используемую для работы с массивами. Это также общепринятый пакет для обработки массивов, который предоставляет обширные математические функции, рутину линейной алгебры, преобразования Фурье и многое другое.

NumPy позволяет использовать меньше памяти для хранения данных по сравнению с обычными списками в Python и также помогает создавать многомерные массивы. Именно поэтому NumPy используется в Python.

2. Как определить NumPy в Python?

NumPy в Python определяется как фундаментальный пакет для научных вычислений, который помогает выполнять сложные математические и другие виды операций над большим количеством данных.

3. Где используется NumPy?

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

4. Что лучше — NumPy или pandas?

Проанализируйте приведенные ниже пункты и решите, что лучше использовать.

  • NumPy и pandas — наиболее используемые библиотеки в области Data Science, ML и AI.
  • Обе библиотеки позволяют сэкономить n-е количество строк кода.
  • Обе библиотеки имеют открытый исходный код.
  • NumPy используется для быстрых научных вычислений, а pandas — для манипулирования данными, их анализа и очистки.

От редакции Pythonist: если вы не знакомы с pandas, вот полезная ознакомительная статья — «Полное руководство по Pandas для начинающих».

5. В чем разница между NumPy и pandas?

NumPyPandas
Numpy создает объект n-мерного массива.Pandas создает DataFrame и Series.
Массив Numpy содержит данные одинаковых типовPandas хорошо подходит для работы с табличными данными
Numpy требует меньше памятиPandas требует больше памяти по сравнению с NumPy
NumPy поддерживает многомерные массивы.Pandas поддерживает двумерные массивы

6. Что такое массив NumPy?

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

7. На каком языке написана NumPy?

NumPy — это библиотека Python, которая частично написана на Python, а большая часть написана на C или C++. Кроме того, она поддерживает расширения на других языках, в частности, на C++ и Fortran.

Перевод статьи «GPython NumPy Tutorial – 2023».