Часть 1: Введение в NumPy

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 из списка. Тип нашей переменной arrnumpy.ndarray. Здесь ndarray означает N-мерный массив.

Размеры или оси

В NumPy измерения называются осями (множественное число от axis). Мне нравится думать об оси как о линии, вдоль которой можно хранить элементы. Простой список или одномерный массив можно представить в виде:

Теперь мы рассмотрим следующее:

  1. Скаляры (0D массивы)
  2. Векторы (одномерные массивы)
  3. Матрицы (двумерные массивы)
  4. 3D массивы
  5. четырехмерные массивы

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.

Оцените статью
Procodings.ru
Добавить комментарий