Хочешь уверенно проходить IT-интервью?

Мы понимаем, как сложно подготовиться: стресс, алгоритмы, вопросы, от которых голова идёт кругом. Но с AI тренажёром всё гораздо проще.
💡 Почему Т1 тренажёр — это мастхэв?
- Получишь настоящую обратную связь: где затык, что подтянуть и как стать лучше
- Научишься не только решать задачи, но и объяснять своё решение так, чтобы интервьюер сказал: "Вау!".
- Освоишь все этапы собеседования, от вопросов по алгоритмам до диалога о твоих целях.
Зачем листать миллион туториалов? Просто зайди в Т1 тренажёр, потренируйся и уверенно удиви интервьюеров. Мы не обещаем лёгкой прогулки, но обещаем, что будешь готов!
Реклама. ООО «Смарт Гико», ИНН 7743264341. Erid 2VtzqwP8vqy
Трудность NumPy в том, что операции над многомерными массивами бывает сложно представить. Хаус Лин подготовил шпаргалки, которые сделают преобразование массивов нагляднее. Руководство подойдёт и для знакомства с NumPy.
1. Создаем массив NumPy
Аналог range для массивов. Чтобы создать простой массив, используем функцию np.arange()
. Удобно взять небольшое составное число, например, 12.
import numpy as np
a1 = np.arange(1, 13) # числа от 1 до 12
print(a1.shape)
> (12,)
print(a1)
> [ 1 2 3 4 5 6 7 8 9 10 11 12]

2. Изменяем форму с помощью метода reshape()
Оси и измерения. Чтобы изменить форму массива a1
, используем метод reshape()
. Преобразуем одномерный массив из 12 чисел в двумерную таблицу размером 3×4. Первое число – количество строк, второе – столбцов. Строки соответствуют оси (англ. axis) 0, столбцы – оси 1. Ещё их называют измерениями (англ. dimensions).
a1_2d = a1.reshape(3, 4)
print(a1_2d.shape)
> (3, 4)
print(a1_2d)
> [[ 1 2 3 4]
[ 5 6 7 8]
[ 9 10 11 12]]

Автоматическое вычисление размерности. Если нужно, чтобы NumPy сам определил размер незаданного измерения, передайте на этой позиции значение -1
:
a1.reshape(3, 4)
a1.reshape(-1, 4) # то же самое, что a1.reshape(3, 4)
a1.reshape(3, 4)
a1.reshape(3, -1) # то же самое, что a1.reshape(3, 4)
a1.reshape(2, 6)
a1.reshape(2, -1) # то же самое, что a1.reshape(2, 6)
3. Изменяем форму по разным направлениям
Порядок переноса С. По умолчанию reshape()
перестраивает исходный массив по оси 0. То есть в нашем примере отдельные числа из одномерного массива «переносятся» в двумерный построчно. Поведение можно изменить, передав значение параметру order
. Дефолтный метод похож на то, как преобразование реализовано в C. Параметр order
по умолчанию имеет значение 'C'
:
a1.reshape(3, 4)
a1.reshape(3, 4, order='C') # даст идентичный результат
Порядок переноса Fortran. Если вы привыкли к тому, как преобразуются массивы в MATLAB, то это делается так же, как в Fortran. Поэтому используйте значение 'F'
:
a1.reshape(3, 4, order='F') # столбец за столбцом
> [[ 1 4 7 10]
[ 2 5 8 11]
[ 3 6 9 12]]

Какую размерность имеет исходный массив a1
? Может показаться, что массив a1 имеет размерность (1, 12)
. Но это одномерный массив с размерностью(12, )
. Чтобы преобразовать одномерный массив к двумерному, используем метод reshape()
:
print(a1) # какая форма?
> [ 1 2 3 4 5 6 7 8 9 10 11 12]
print(a1.shape)
> (12,)
a1_1_by_12 = a1.reshape(1, -1) # преобразуем к 1x12
print(a1_1_by_12) # обратите внимание на двойные скобки
> [[ 1 2 3 4 5 6 7 8 9 10 11 12]]
print(a1_1_by_12.shape) # двумерный массив
> (1, 12)
4. Схлопываем массив до одномерного
Из 2D в 1D. Метод ravel()
преобразует многомерные массивы в одномерные. Тот же параметр order
определяет, «схлопнется» ли массив построчно или столбец за столбцом:
print(a1_2d)
> [[ 1 2 3 4]
[ 5 6 7 8]
[ 9 10 11 12]]
print(a1_2d.ravel()) # строка за строкой
> [ 1 2 3 4 5 6 7 8 9 10 11 12]
print(a1_2d.ravel(order='F')) # столбец за столбцом
> [ 1 5 9 2 6 10 3 7 11 4 8 12]
5. Повышаем размерность, сшивая массивы друг с другом

Создадим два массива:
a1 = np.arange(1, 13)
print(a1)
> [ 1 2 3 4 5 6 7 8 9 10 11 12]
a2 = np.arange(13, 25)
print(a2)
> [13 14 15 16 17 18 19 20 21 22 23 24]
Чтобы соединить два одномерных масива в двумерный, используем метод np.stack()
. Параметр axis
указывает индекс оси в результирующем массиве, по которой соединяются входные. По умолчанию axis = 0
, и массивы стыкуются строка к строке:
stack0 = np.stack((a1, a1, a2, a2))
print(stack0.shape)
> (4, 12)
print(stack0)
> [[ 1 2 3 4 5 6 7 8 9 10 11 12]
[ 1 2 3 4 5 6 7 8 9 10 11 12]
[13 14 15 16 17 18 19 20 21 22 23 24]
[13 14 15 16 17 18 19 20 21 22 23 24]]
Чтобы соединить массивы столбец к столбцу, явным образом передаем axis = 1
:
stack1 = np.stack((a1, a1, a2, a2), axis=1)
print(stack1.shape)
> (12, 4)
print(stack1)
> [[ 1 1 13 13]
[ 2 2 14 14]
[ 3 3 15 15]
[ 4 4 16 16]
[ 5 5 17 17]
[ 6 6 18 18]
[ 7 7 19 19]
[ 8 8 20 20]
[ 9 9 21 21]
[10 10 22 22]
[11 11 23 23]
[12 12 24 24]]
Как не повышать число измерений? Функция hstack()
соединяет массивы горизонтально без изменения размерности. Если применить ее к одномерным массивам, получится длинный одномерный массив:
stack_long = np.hstack((a1, a2))
print(stack_long.shape)
> (24,)
print(stack_long)
> [ 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24]
6. Создаем трехмерный массив
Где применяются многомерные массивы? Массивы, живущие в трёх и более измерениях, активно используются в глубоком обучении. Например, для операций с изображениями. В работе с нейросетями преобразование многомерных массивов – обычное дело.
Для начала создадим два двумерных массива размером 3×4:
a1 = np.arange(1, 13).reshape(3, -1)
a2 = np.arange(13, 25).reshape(3, -1)
print(a1)
> [[ 1 2 3 4]
[ 5 6 7 8]
[ 9 10 11 12]]
print(a2)
> [[13 14 15 16]
[17 18 19 20]
[21 22 23 24]]

Теперь соберём из них трёхмерный массив:
a3_0 = np.stack((a1, a2)) # дефолтное axis=0, одна плоскость ложится на другую
a3_1 = np.stack((a1, a2), axis=1)
a3_2 = np.stack((a1, a2), axis=2)
print(a3_0.shape)
> (2, 3, 4)
print(a3_1.shape)
> (3, 2, 4)
print(a3_2.shape)
> (3, 4, 2)

Как выглядят массивы:
print(a3_0)
> [[[ 1 2 3 4]
[ 5 6 7 8]
[ 9 10 11 12]]
[[13 14 15 16]
[17 18 19 20]
[21 22 23 24]]]
print(a3_1)
> [[[ 1 2 3 4]
[13 14 15 16]]
[[ 5 6 7 8]
[17 18 19 20]]
[[ 9 10 11 12]
[21 22 23 24]]]
print(a3_2)
> [[[ 1 13]
[ 2 14]
[ 3 15]
[ 4 16]]
[[ 5 17]
[ 6 18]
[ 7 19]
[ 8 20]]
[[ 9 21]
[10 22]
[11 23]
[12 24]]]
Чтобы извлечь плоскость массива a1
из трехмерного, нужно передать 0
по соответствующему индексу оси:
print(a1)
> [[ 1 2 3 4]
[ 5 6 7 8]
[ 9 10 11 12]]
a3_0[0, :, :]
a3_1[:, 0, :]
a3_2[:, :, 0]
Чтобы то же самое сделать для двумерного массива a2
, на тех же позициях вместо 0
отправляем индекс 1
. Символы двоеточия указывают, что нужно взять все элементы соответствующей оси.
7. Схлопываем многомерные массивы
Метод ravel()
действует и для массивов с числом размерностей больше 2:

print(a3_0)
> [[[ 1 2 3 4]
[ 5 6 7 8]
[ 9 10 11 12]]
[[13 14 15 16]
[17 18 19 20]
[21 22 23 24]]]
print(a3_0.ravel())
> [ 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24]
print(a3_0.ravel(order='F'))
> [ 1 13 5 17 9 21 2 14 6 18 10 22 3 15 7 19 11 23 4 16 8 20 12 24]
8. Изменяем форму многомерных массивов
Метод reshape()
также работает с массивами любой размерности. Главное условие, которое нужно соблюдать – количество элементов в массиве не должно меняться:
print(a3_0) # исходный размер 2x3x4
> [[[ 1 2 3 4]
[ 5 6 7 8]
[ 9 10 11 12]]
[[13 14 15 16]
[17 18 19 20]
[21 22 23 24]]]
print(a3_0.reshape(4, -1)) # преобразуем к 4x6
> [[ 1 2 3 4 5 6]
[ 7 8 9 10 11 12]
[13 14 15 16 17 18]
[19 20 21 22 23 24]]
print(a3_0.reshape(4, -1, order='F')) # делаем то же самое, но в F-стиле
> [[ 1 9 6 3 11 8]
[13 21 18 15 23 20]
[ 5 2 10 7 4 12]
[17 14 22 19 16 24]]
print(a3_0.reshape(4, 2, 3)) # преобразуем к трехмерному массиву другой формы
> [[[ 1 2 3]
[ 4 5 6]]
[[ 7 8 9]
[10 11 12]]
[[13 14 15]
[16 17 18]]
[[19 20 21]
[22 23 24]]]
Заключение
Напоследок приведем изображение со всеми элементами рассказа вместе (оригинальный pdf). Напишите нам в комментариях, если что-то осталось непонятным и требует пояснений.

Комментарии