#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,
- является объектом последовательности, отличной от кортежа,
- ndarray (типа данных integer или bool),
- кортеж, содержащий по крайней мере один объект последовательности или 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,), и поскольку это происходит по третьему индексу, он вставляется в третий индекс результирующего массива.
Любые предложения и улучшения приветствуются.
Ссылка:-
Ответ №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)?