У меня есть переменная х, которая имеет форму (2,2,50,100).
У меня также есть массив y, равный np.array ([0,10,20]). Странная вещь случается, когда я индексирую x [0,:,:, y].
x = np.full((2,2,50,100),np.nan)
y = np.array([0,10,20])
print(x.shape)
(2,2,50,100)
print(x[:,:,:,y].shape)
(2,2,50,3)
print(x[0,:,:,:].shape)
(2,50,100)
print(x[0,:,:,y].shape)
(3,2,50)
Почему последний выводит (3,2,50), а не (2,50,3)?
Ответы:
Вот как NumPy использует расширенную индексацию для трансляции форм массива. Когда вы передаете a
0
для первого индекса иy
для последнего индекса, numpy будет транслировать,0
чтобы иметь ту же форму, что иy
. Эквивалентность имеет местоx[0,:,:,y] == x[(0, 0, 0),:,:,y]
. вот примерТеперь, поскольку вы фактически передаете два набора индексов, вы используете API расширенного индексирования для формирования (в данном случае) пар индексов.
Который имеет первое измерение, которое равно длине
y
. Это то, что вы видите.В качестве примера рассмотрим массив с 4 измерениями, которые описаны в следующем фрагменте:
x
имеет действительно легко понять последовательную форму, которую мы можем теперь использовать, чтобы показать, что происходит ...Первое измерение похоже на наличие двух книг Excel, второе измерение похоже на наличие трех листов в каждой книге, третье измерение похоже на наличие 4 строк на листе, а последнее измерение составляет 5 значений для каждой строки (или столбцов на листе).
Глядя на это так, спрашивая
x[0,:,:,0]
, можно сказать: «в первой книге, для каждого листа, для каждой строки, дайте мне первое значение / столбец».Но теперь с расширенным индексированием мы можем думать
x[(0,0,0),:,:,y]
как «в первой книге, для каждого листа, для каждой строки, дайте мнеy
значение th / столбец. Хорошо, теперь сделайте это для каждого значенияy
»Где он сходит с ума, так это то, что numpy будет транслироваться, чтобы соответствовать внешним измерениям массива индекса. Поэтому, если вы хотите выполнить ту же операцию, что и выше, но для ОБА «книг Excel», вам не нужно зацикливаться и объединять. Вы можете просто передать массив в первое измерение, но он ДОЛЖЕН иметь совместимую форму.
Передача целого числа транслируется на
y.shape == (3,)
. Если вы хотите передать массив в качестве первого индекса, только последнее измерение массива должно быть совместимо сy.shape
. Т.е. последнее измерение первого индекса должно быть 3 или 1.В документах нашел краткое объяснение: https://docs.scipy.org/doc/numpy/reference/arrays.indexing.html#combining-advanced-and-basic-indexing.
Редактировать:
Исходя из первоначального вопроса, чтобы получить одну строку нужного сублицензирования, вы можете использовать
x[0][:,:,y]
:Однако, если вы пытаетесь назначить этим сублимам, вы должны быть очень осторожны, когда смотрите на общий вид памяти исходного массива. В противном случае присваивание будет не исходному массиву, а копии.
Общая память возникает только тогда, когда вы используете целое число или фрагмент для подмножества вашего массива, то есть
x[:,0:3,:,:]
илиx[0,:,:,1:-1]
.И в вашем оригинальном вопросе, и в моем примере
y
нет ни int, ни slice, поэтому всегда будет назначаться копия оригинала.НО! Поскольку ваш массив для
y
может быть выражен в виде среза, вы МОЖЕТЕ получить назначаемое представление вашего массива через:Здесь мы используем фрагмент,
0:21:10
чтобы получить каждый индекс, который будет вrange(0,21,10)
. Мы должны использовать,21
а не20
потому, что точка останова исключена из среза, как вrange
функции.Таким образом, в принципе, если вы можете создать срез, который соответствует вашим критериям сублицензирования, вы можете сделать назначение.
источник
Это называется
combining advanced and basic indexing
. Incombining advanced and basic indexing
, numpy, сначала выполните индексацию в расширенной индексации, а подпространство / объедините результат с измерением базовой индексации.Пример из документов:
так, на
x[0,:,:,y]
,0
иy
предварительны индексации. Они передаются вместе, чтобы дать измерение(3,)
.Это
(3,)
привязывает к началу 2-го и 3-го измерения, чтобы сделать(3, 2, 50)
Чтобы увидеть, что 1-е и последнее измерение действительно передаются вместе, вы можете попробовать изменить
0
их,[0,1]
чтобы увидеть ошибку вещанияисточник