Есть ли канонический способ получения подмассива 0D numpy?

Учитывая numpy ndarray и индекс:

a = np.random.randint(0,4,(2,3,4))
idx = (1,1,1)

есть ли чистый способ получить подмассив 0D a в idx?

Что-то эквивалентное

a[idx + (None,)].squeeze()

но менее хакерский?

Обратите внимание, что @filippo умный

a[idx][...]

не эквивалентен. Во-первых, это не работает для массивов объектов. А если серьезно, он возвращает не подмассив, а новый массив:

b = a[idx][...]
b[()] = 7
a[idx] == 7
# False

person Paul Panzer    schedule 21.12.2017    source источник


Ответы (2)


b = a[idx+(Ellipsis,)]

Я тестирую на одной машине и пишу это на планшете, поэтому не могу дать свой обычный проверочный код.

Возможно, лучшее объяснение документации (или констатация факта):

https://docs.scipy.org/doc/numpy-1.13.0/reference/arrays.indexing.html#detailed-notes

Когда многоточие (...) присутствует, но не имеет размера (т.е. заменяет ноль :), результатом всегда будет массив. Представление, если расширенный индекс отсутствует, в противном случае — копия.

person hpaulj    schedule 21.12.2017
comment
Забавно, на самом деле это еще один контрпример к моему самому первому сообщению на SO, и угадайте, кто ответил на этот вопрос... - person Paul Panzer; 21.12.2017
comment
Хорошо, позвольте мне предложить вам объяснить, почему это действительно работает! - person Paul Panzer; 21.12.2017
comment
В a[1,1,1,...] Ellipsis означает заполнение оставшихся измерений, например [:]*. Это может быть 2, 1 или, в данном случае, 0. Я нашел примечание к документации, в котором говорится, что происходит, даже если оно не объясняет точно действие. - person hpaulj; 21.12.2017
comment
Спасибо! Это полный ответ. - person Paul Panzer; 21.12.2017

Не уверен, что правильно понял, что вы хотите, это выглядит достаточно чисто?

In [1]: import numpy as np

In [2]: a = np.random.randint(0,4,(2,3,4))
   ...: idx = (1,1,1)
   ...: 

In [3]: a[idx]
Out[3]: 2

In [4]: a[idx][...]
Out[4]: array(2)

РЕДАКТИРОВАТЬ: обратите внимание, что это возвращает копию, а не 0D-представление того же массива

person filippo    schedule 21.12.2017
comment
Вау, я этого не знал! Спасибо! Но, увы, с массивами объектов это не работает. Я обновил вопрос. - person Paul Panzer; 21.12.2017
comment
a[idx+(Ellipsis,)] вроде работает. Он сочетает в себе обе идеи. a[idx] для массива объектов возвращает int. Для массива int возвращает np.int32. Это уже близкий родственник массива 0d. Посмотрите на его методы и атрибуты. - person hpaulj; 21.12.2017
comment
@hpaulj Да! Вот и все. Я думаю, что это стоит ответа. - Близкий родственник, да, но это изменчивость и обмен данными с исходным массивом, который мне нужен. - person Paul Panzer; 21.12.2017
comment
Вы правы, расширенная индексация всегда копирует, если я правильно помню. Не могу придумать ничего лучше, чем @hpaulj, пожалуйста, добавьте ответ! - person filippo; 21.12.2017