NumPy. Работа с массивами и матрицами


Библиотека для работы с данными NumPy

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

Математические алгоритмы, реализованные на интерпретируемых языках (например, Python), часто работают гораздо медленнее тех же алгоритмов, реализованных на компилируемых языках (например, Фортран, Си, Java). Библиотека NumPy предоставляет реализации вычислительных алгоритмов (в виде функций и операторов), оптимизированных для работы с многомерными массивами. 
В результате, любой алгоритм, который может быть выражен в виде последовательности операций над массивами (матрицами) и реализованный с использованием NumPy, работает достаточно быстро.

NumPy (числовой Питон) - это основная математическая библиотека для работы с данными. Данная библиотека лежит в основе других библиотек для работы с задачами машинного обучения или анализа данных (например, Pandas (работа с табличными данными), SciPy (методы оптимизации и научные расчеты), Matplotlib (построение графиков)).

 

Работа с NumPy

Для того, чтобы начать работать с библиотекой numpy ее нужно импортировать в начале программы как и любую другую библиотеку,
import numpy
или так (что используется чаще)
import numpy as np



Векторы NumPy

Вектор (или массив) в NumPy - это упорядоченный набор однородных данных.

К элементу вектора можно обратиться по его индексу, точно также как это делается в списках. Каждый элемент вектора имеет свое определенное место, которое задается при создании.
Все элементы вектора имеют один и тот же тип данных (int, str, bool и др.).

Создание вектора
Чтобы создать вектор, необходимо воспользоваться конструктором numpy.array (итерируемый объект).
В скобках указывается любой итерируемый объект: кортеж, список, range() и др.
 
Пример 
import numpy as np
print(np.array((1,2,3,4,5))) # вектор из кортежа
print(np.array([1,2,3,4,5])) # вектор из списка
print(np.array(range(5))) # вектор из генератора

Работа с элементами вектора

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

Пример
1
2
3
4
5
6
7
import numpy as np

V = np.array((1,2,3,4))
print(V[0])    # 1 
print(V[-1])   # 4 
print(V[1:-2]) # [2]  
print(V[::2])  # [1 3]

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

Пример
import numpy as np

V = np.array([1,-2,3,-4,5])
# выбор первых двух элементов вектора
print(V[np.array((True, True, False, False, False))])    # [ 1 -2]

# выбор положительных элементов вектора
print(V[V > 0])    # [1 3 5]

# выбор четных элементов вектора
print(V[V % 2 == 0])    # [-2 -4]

Способы создания массивов и матриц

Другие полезные способы создания массивов и матриц.

Пример
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
import numpy as np

# Одномерный массив нулей
print(np.zeros(5))   #[0. 0. 0. 0. 0.]

# Двумерный массив нулей
print(np.zeros((2, 3)))   # [[0. 0. 0.]
                          #  [0. 0. 0.]]

# Трёхмерный массив единиц
print(np.ones((2,3,4)))   # [[[1. 1. 1. 1.]
                          #   [1. 1. 1. 1.]
                          #   [1. 1. 1. 1.]]
                          # 
                          #  [[1. 1. 1. 1.]
                          #   [1. 1. 1. 1.]
                          #   [1. 1. 1. 1.]]]

# Массив нулей с указанием типа
print(np.zeros(5, dtype=int)) # [0 0 0 0 0]

# Массив на основе списка списков
print(np.array([[1,2.0],[0,0],(1,3.)]))   # [[1. 2.]
                                          #  [0. 0.]
                                          #  [1. 3.]]

# Массив, заполненный элементами арифметической прогрессии, начиная с 0
print(np.arange(10))   # [0 1 2 3 4 5 6 7 8 9]

# Арифметическая прогрессия с указанием типа
print(np.arange(2, 10, dtype=float))   # [2. 3. 4. 5. 6. 7. 8. 9.]

# Арифметическая прогрессия с нецелой разностью
print(np.arange(2, 3, 0.1))  # [2.  2.1 2.2 2.3 2.4 2.5 2.6 2.7 2.8 2.9]

# Арифметическая прогрессия с заданным количеством членов
print(np.linspace(1., 4., 6))  # [1.  1.6 2.2 2.8 3.4 4. ]

Нулевые элементы массива
 
Функция nonzero(V) 
Результат представляет собой кортеж массивов. Каждый такой массив соответствует отдельной оси исходного массива и содержит индексы с ненулевыми элементами в этом массиве.
V - массив NumPy или подобный массиву объект.
Возвращает функция кортеж Python (tuple) - кортеж с массивами индексов ненулевых элементов исходного массива V.
 
Функция count_nonzero(V) 
Работа данной функции основана на встроенном методе __bool__() объектов языка Python, который проверяет их истинность. Отсюда следует, что функция count_nonzero() на самом деле способна работать не только с числами, но и любыми объектами, которые могут быть как истинными, так и ложными.
V - массив NumPy или подобный массиву объект.
Возвращает функция количество ненулевых элементов массива вдоль указанной оси.

Диагональные массивы

Функция diag(V, k=0) позволяет извлекать диагональ из массива, а также строить диагональные массивы из одномерных массивов.
V - подобный массиву объект, двумерные или одномерные массивы, матрицы, списки или кортежи, а также любая функция или объект с методом, возвращающие список или кортеж.
k - индекс диагонали (необязательный).
По умолчанию k = 0, что соответствует главной диагонали. Положительное значение k смещает диагональ вверх, отрицательное - вниз.

Пример создания диагонального массива:
V = np.diag([1, 4, 5])
print(V)
Массив V будет иметь вид
[[1 0 0]
 [0 4 0]
 [0 0 5]]


Пример получения диагонального массива из матрицы
arr = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
print(np.diag(arr))       # [1 5 9]

Функция возвращает массив NumPy (ndarray) - указанную диагональ массива или диагональный массив из указанного одномерного массива.

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

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

Пример
1
2
3
4
5
6
7
8
# Функция reshape() изменяет форму массива без изменения его данных.
x = np.arange(12).reshape(3, 4)
print(x)                           # [[ 0  1  2  3]
                                   #  [ 4  5  6  7]
                                   #  [ 8  9 10 11]]                     

# Для доступа к элементу, указываем его координаты через запятую
print(x[1, 2])     # 6