Подтвердить что ты не робот

Как метод NumPy transpose() переставляет оси массива?

In [28]: arr = np.arange(16).reshape((2, 2, 4))

In [29]: arr
Out[29]: 
array([[[ 0,  1,  2,  3],
        [ 4,  5,  6,  7]],

       [[ 8,  9, 10, 11],
        [12, 13, 14, 15]]])


In [32]: arr.transpose((1, 0, 2))
Out[32]: 
array([[[ 0,  1,  2,  3],
        [ 8,  9, 10, 11]],

       [[ 4,  5,  6,  7],
        [12, 13, 14, 15]]])

Когда мы передаем кортеж целых чисел в функцию transpose(), что происходит?

Чтобы быть конкретным, это трехмерный массив: как NumPy преобразует массив, когда передаю кортеж осей (1, 0 ,2)? Можете ли вы объяснить, к какой строке или столбцу относятся эти целые числа? А что такое номера оси в контексте NumPy?

4b9b3361

Ответ 1

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

>>> arr.strides
(64, 32, 8)

>>> arr.transpose(1, 0, 2).strides
(32, 64, 8)

Обратите внимание, что операция транспонирования заменила шаги для оси 0 и оси 1. Длина этих осей также была заменена (обе длины 2 в этом примере).

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


Визуализация шагов

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

Теперь наш 3D-массив arr выглядит так (с мечеными осями):

введите описание изображения здесь

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

введите описание изображения здесь

Так как каждое целое число занимает 8 байт памяти (мы используем тип int64), значение шага для каждого измерения в 8 раз больше значений, которые нам нужно прыгать. Например, чтобы перемещаться вдоль оси 1, четыре значения (32 байта) подпрыгивают, а для перемещения по оси 0 необходимо поднять восемь значений (64 байта).

Когда мы пишем arr.transpose(1, 0, 2), мы обмениваем оси 0 и 1. Транспонированный массив выглядит следующим образом:

введите описание изображения здесь

Все, что нужно сделать NumPy, - это обмен информацией о шаге для оси 0 и оси 1 (ось 2 не изменяется). Теперь мы должны двигаться дальше по оси 1, чем ось 0:

введите описание изображения здесь

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

Ответ 2

Как объясняется в документации:

По умолчанию измените размеры, иначе переместите оси в соответствии с указанными значениями.

Итак, вы можете передать необязательный параметр axes, определяющий новый порядок измерений.

например. перенос первых двух измерений матрицы пикселов VGA VGA:

 >>> x = np.ones((480, 640, 3))
 >>> np.transpose(x, (1, 0, 2)).shape
 (640, 480, 3)