Numpy: Поведение при индексировании с помощью эллипсов не интуитивно понятно.

Созданный на 27 июл. 2020  ·  6Комментарии  ·  Источник: numpy/numpy

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

a = np.array([[[False]]])
a[0:0, 0, ..., [0]]
Out[23]: array([], shape=(1, 0), dtype=bool)
a[0:0, 0,  [0]]
Out[24]: array([], shape=(0, 1), dtype=bool)

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

Информация о версии Numpy / Python:

1.17.3 3.7.5 (по умолчанию, 25 октября 2019 г., 10:52:18)
[Clang 4.0.1 (теги / RELEASE_401 / final)]

04 - Documentation 33 - Question 57 - Close?

Самый полезный комментарий

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

Почему он должен быть действительно «невидимым»? ... должен вести себя одинаково для любого количества измерений. Для этого он должен запускать транспонирование во всех случаях. То есть представьте что-то, организованное как series, ..., color где ... определяется пользователем и может быть 0-d. Если бы вы написали программу для обработки этих данных, вам потребовалось бы, чтобы индексация была предсказуемо транспонирована независимо от того, ... чего

В конце концов, это просто сбивает с толку, и нам придется более серьезно подобрать .oindex , .vindex и т. Д., Чтобы решить эту проблему: https://numpy.org/neps/nep- 0021-advanced-indexing.html

Все 6 Комментарий

Это выглядит как особенно неприятный угловой случай - я думаю, мы считаем, что ... заставляет два расширенных индекса, 0 и [0] , считаться несмежными, хотя оси, которые они индексируют, являются соседними.

Мы столкнулись с этой проблемой при попытке воспроизвести индексирование numpy. Я думаю, что это странное взаимодействие между двумя правилами:

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

Этот особый случай запускается, потому что кортеж 0-d (когда ... используется со всеми присутствующими индексами) по-прежнему считается базовым индексным блоком, хотя он действительно должен быть невидимым.

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

Почему он должен быть действительно «невидимым»? ... должен вести себя одинаково для любого количества измерений. Для этого он должен запускать транспонирование во всех случаях. То есть представьте что-то, организованное как series, ..., color где ... определяется пользователем и может быть 0-d. Если бы вы написали программу для обработки этих данных, вам потребовалось бы, чтобы индексация была предсказуемо транспонирована независимо от того, ... чего

В конце концов, это просто сбивает с толку, и нам придется более серьезно подобрать .oindex , .vindex и т. Д., Чтобы решить эту проблему: https://numpy.org/neps/nep- 0021-advanced-indexing.html

Я согласен с аргументом

Я не знал об этом предложении, спасибо за ссылку @seberg!

Позвольте мне перефразировать, чтобы убедиться, что я понимаю ваш аргумент. Скажем, мы помечаем расширенные индексы A и базовые индексы B и, как указано выше, я вызываю операцию переупорядочения (обобщенную) транспонированием. В вашем примере у нас есть четыре случая:

  • [A1, ..., A2] и [B1, ... A1] : эти случаи запускают транспонирование в [A1, A2, ....] и [A1, B1, ...] независимо от того, как ... раскрывается.
  • [A1, ..., B1] и [B1, ..., B2] : в этих случаях нет.

Эти правила согласованы, если вы знаете, к какому классу (A или B) принадлежат series и color , независимо от того, как ... расширяется. Это эквивалентно обработке ... как (потенциально 0-d) блока базовых индексов. Обработка 0-d ... как особого случая была бы плохой, потому что транспонирование будет зависеть от того, передал ли пользователь двумерный массив или 3-х или более-D. Я согласен, это плохое место.

Моя интуиция, что блоки 0-d не должны работать, было обусловлено поведением кортежей, где для любых i

i: int
M: Tuple[int, ...]
N = ()
assert M[:i] + N + M[i:] == M

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

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

Спасибо, что заглянули! Я могу отправить документ по связям с общественностью, если хотите.

@antonl a doc PR всегда приветствуется, здесь есть много возможностей для улучшения.

Была ли эта страница полезной?
0 / 5 - 0 рейтинги

Смежные вопросы

kevinzhai80 picture kevinzhai80  ·  4Комментарии

inducer picture inducer  ·  3Комментарии

toddrjen picture toddrjen  ·  4Комментарии

dmvianna picture dmvianna  ·  4Комментарии

keithbriggs picture keithbriggs  ·  3Комментарии