Массив Python, индексированный списком, но размеры массива изменены

#python #numpy #numpy-ndarray #array-broadcasting

#python #numpy #numpy-ndarray #массив-широковещательная передача

Вопрос:

Я пытаюсь проиндексировать массив (имеет пять измерений), используя список. Однако в определенной ситуации массив переставляется.

Скажем, a имеет форму (3,4,5,6,7), т. е.,

 >>> a = np.zeros((3,4,5,6,7))
>>> a.shape
(3, 4, 5, 6, 7)
  

Использование списка для индексации этого массива в третьем измерении выглядит нормально:

 >>> a[:,:,[0,3],:,:].shape
(3, 4, 2, 6, 7)
  

Однако, если массив был проиндексирован в следующей ситуации, третье измерение переставляется в крайнее левое:

 >>> a[0,:,[0,1],:,:].shape
(2, 4, 6, 7)
  

Кто-нибудь может пролить на это свет?

Ответ №1:

Базовая нарезка:-

Базовая нарезка происходит при использовании объекта slice.Обычно объект среза создается как массив[(start:stop:step)]. Многоточие и новая ось также подпадают под это.

Пример:- Одномерный массив

 >>x=np.arange(10)    
>>x[2:10:3]
 array([2, 5, 8])
  

Пример:- 2D массив

 >>>x = np.array([[1,2,3], [4,5,6]])
>>>x[1:2]
array([[4, 5, 6]])
  

Пример:- 3D-массив

 >>>x = np.array([[[1],[2],[3]], [[4],[5],[6]]])
>>> x[0:1]
array([[[1],
        [2],
        [3]]])
  

В приведенном выше примере количество заданных фрагментов (obj) меньше, чем общее количество измерений массива. Если количество объектов в кортеже выбора меньше N, то оно предполагается для любых последующих измерений.

Расширенная нарезка:-

Расширенная индексация запускается, когда объект выбора, obj,

  1. является объектом последовательности, отличной от кортежа,
  2. ndarray (типа данных integer или bool),
  3. кортеж, содержащий по крайней мере один объект последовательности или ndarray (типа данных integer или bool).

Существует два типа расширенной индексации: целочисленная и логическая.

Целочисленное индексирование:-

Целочисленная индексация массива позволяет выбирать произвольные элементы в массиве на основе их N-мерного индекса. Каждый массив целых чисел представляет некоторое количество индексов в этом измерении.

Когда индекс состоит из такого количества массивов целых чисел, сколько размеров имеет индексируемый массив, индексация выполняется прямолинейно, но отличается от нарезки.

Пример:-

 >>a = np.array([[1,2,3],[4,5,6],[7,8,9]])
>>a[[0,1,2],[0,1,1]]
array([1, 5, 8])
  

Визуализация массива

Приведенный выше пример выводит:
a [0,0],a [1,0], a [2,1]

Помните:- Таким образом, целочисленное индексирование сопоставляется между двумя индексами.

Теперь к вашему вопросу:-

 >>>a=np.array([3,4,5])
>>>a[0,:,[0,1]]
  

Первый случай:-

Это имеет вид, что x[arr1,:,arr2].
arr1 и arr2 являются расширенными индексами.Мы считаем, что 0 также является расширенным индексом.

Если расширенные индексы разделены срезом, многоточием или новой осью, то размеры, полученные в результате операции расширенного индексирования, идут первыми в результирующем массиве, а измерения подпространства — после этого.

По сути, это означает, что размерность [0,1] занимает первое место в массиве. Я оставляю 0, поскольку у него нет измерения.

 >>>a[0,:,[0,1]].shape
(2,4)
  

Второй случай:-

Это имеет вид, x[:,:,arr1]. только здесь arr1 является расширенным индексом.

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

По сути, это означает, что размерность [0,1] находится в соответствующей позиции, указанной в индексе массива.

 >>>a[0:1,:,[0,1]].shape
(1,4,2)
  

[0,1] имеет форму (2,), и поскольку это происходит по третьему индексу, он вставляется в третий индекс результирующего массива.

Любые предложения и улучшения приветствуются.

Ссылка:-

  1. Numpy_Docs

Ответ №2:

Спасибо @Hari_Sheldon за ответ. Теперь я видел, что print сделала с массивом a, но я все еще не понимаю, почему Python берет эти столбцы, указанные в списке, и помещает их в виде строк в крайнем левом положении. Есть ли какая-либо ссылка, объясняющая причину?

И в некоторых ситуациях эта перестановка размеров не происходит, т.е.:

 >>> a[0:1,:,[0,3]].shape
(1, 4, 2)
  

Как вы можете видеть, вместо того, чтобы переставлять его в (2, 4), порядок размеров сохраняется!

Комментарии:

1. Вы ответили, в чем вы должны прокомментировать. Вы можете понять, если попробуете разницу между тем, что a[0] and a[0:1] один возвращает shape () , а другой возвращает shape (1,) для одномерного списка

2. Да, я понимаю правило сохранения вырожденного измерения. Однако я не понимаю, почему сохранение вырожденного измерения предотвращает перестановку массива. Другими словами, почему a[0: 1,0,[0,3]] не возвращает форму (2,1,4)?