NumPy — это библиотека Python, которая в основном используется для работы с массивами. Массив — это коллекция элементов, которые хранятся в памяти рядом друг с другом. Пока просто думайте о них как о списках Python.
NumPy написан на языках Python и C. Вычисления в NumPy выполняются частями, написанными на C, что делает их чрезвычайно быстрыми по сравнению с обычным кодом Python.
Установка
Убедитесь, что Python & Pip установлены на вашем компьютере. Затем откройте командную строку или терминал и запустите
pip install numpy
Создание массивов
Мы можем создать массив NumPy с помощью функции array()
модуля numpy.
import numpy as np
arr = np.array([3, 5, 7, 9])
print(type(arr))
Выход:
<class 'numpy.ndarray'>
Мы только что создали массив NumPy из списка. Тип нашей переменной arr
— numpy.ndarray
. Здесь ndarray
означает N-мерный массив.
Размеры или оси
В NumPy измерения называются осями (множественное число от axis). Мне нравится думать об оси как о линии, вдоль которой можно хранить элементы. Простой список или одномерный массив можно представить в виде:
Теперь мы рассмотрим следующее:
- Скаляры (0D массивы)
- Векторы (одномерные массивы)
- Матрицы (двумерные массивы)
- 3D массивы
- четырехмерные массивы
1) Скаляры (0D массивы)
Скаляр — это просто одно значение.
import numpy as np
s = np.array(21)
print("Number of axes:", s.ndim)
print("Shape:", s.shape)
Выход:
Number of axes: 0
Shape: ()
Здесь мы использовали 2 свойства массива numpy:
2) Векторы (одномерные массивы)
Вектор — это набор значений.
import numpy as np
vec = np.array([-1, 2, 7, 9, 2])
print("Number of axes:", vec.ndim)
print("Shape:", vec.shape)
Выход:
Number of axes: 1
Shape: (5,)
vec.shape[0]
дает нам количество значений в нашем векторе, которое здесь равно 5.
3) Матрицы (двумерные массивы)
Матрица — это набор векторов.
import numpy as np
mat = np.array([
[1, 2, 3],
[5, 6, 7]
])
print("Number of axes:", mat.ndim)
print("Shape:", mat.shape)
Выход:
Number of axes: 2
Shape: (2, 3)
Здесь мы создали матрицу 2×3 (двумерный массив), используя список списков. Поскольку матрица имеет 2 оси, кортеж mat.shape
содержит два значения: первое значение — количество строк, второе — количество столбцов.
Каждый элемент (строка) в двумерном массиве является вектором (одномерный массив).
4) 3D-массивы
3D-массив — это набор матриц.
import numpy as np
t = np.array([
[[1, 3, 9],
[7, -6, 2]],
[[2, 3, 5],
[0, -2, -2]],
[[9, 6, 2],
[-7, -3, -12]],
[[2, 4, 5],
[-1, 9, 8]]
])
print("Number of axes:", t.ndim)
print("Shape:", t.shape)
Выход:
Number of axes: 3
Shape: (4, 2, 3)
Здесь мы создали 3D массив, используя список из 4 списков, которые сами содержат 2 списка.
Каждый элемент в 3D-массиве — это матрица (одномерный массив). Обратите внимание, что последняя матрица в массиве является самой передней на изображении.
5) 4D массивы
Рассмотрев приведенные выше примеры, мы видим закономерность. n-мерный массив — это набор n-1 мерных массивов, для n > 0.
Надеюсь, что теперь вы лучше представляете себе визуализацию многомерных массивов.
Доступ к элементам массива
Как и в списках Python, индексы в массивах NumPy начинаются с 0.
import numpy as np
vec = np.array([-3, 4, 6, 9, 8, 3])
print("vec - 4th value:", vec[3])
vec[3] = 19
print("vec - 4th value (changed):", vec[3])
mat = np.array([
[2, 4, 6, 8],
[10, 12, 14, 16]
])
print("mat - 1st row:", mat[0])
print("mat - 2nd row's 1st value:", mat[1, 0])
print("mat - last row's last value:", mat[-1, -1])
Выход:
vec - 4th value: 9
vec - 4th value (changed): 19
mat - 1st row: [2 4 6 8]
mat - 2nd row's 1st value: 10
mat - last row's last value: 16
Массивы NumPy также поддерживают нарезку.
# continuing the above code
print("vec - 2nd to 4th:", vec[1:4])
print("mat - 1st rows 1st to 3rd values:", mat[0, 0:3])
print("mat - 2nd column:", mat[:, 1])
Вывод:
vec - 2nd to 4th: [4 6 9]
mat - 1st row's 1st to 3rd values: [2 4 6]
mat - 2nd column: [ 4 12]
В последнем примере [:, 1]
говорит «получить 2-е значение из всех строк». Следовательно, на выходе мы получаем 2-й столбец матрицы.
Пример: Индексирование в четырехмерном массиве
Допустим, мы хотим получить доступ к обведенному значению. Оно находится во 2-й строке 2-го столбца последней матрицы 2-го 3D массива. Это много, поэтому не торопитесь. Вот как получить к нему доступ:
arr[2, -1, 1, 1]
Python VS NumPy
В начале заметки я сказал, что вычисления в NumPy чрезвычайно быстры по сравнению с обычным кодом Python. Давайте посмотрим на разницу. Мы создадим два списка с 10 миллионами чисел от 0 до 9 999 999, сложим их поэлементно и измерим время, которое это займет. Затем мы преобразуем оба списка в массивы NumPy и проделаем то же самое.
import numpy as np
import time
l1 = list(range(10000000))
l2 = list(range(10000000))
sum = []
then = time.time()
for i in range(len(l1)):
sum.append(l1[i] + l2[i])
print(f"With just Python: {time.time() - then: .2f}s")
arr1 = np.array(l1)
arr2 = np.array(l2)
then = time.time()
sum = arr1 + arr2
print(f"With NumPy: {time.time() - then: .2f}s")
Выход:
With just Python: 2.30s
With NumPy: 0.14s
В этом случае NumPy оказался в 16 раз быстрее, чем необработанный Python.