Numpy расширенная индексация, bool vs. int IndexError: слишком много индексов для массива - PullRequest
0 голосов
/ 08 ноября 2019

Попытка использовать цифровую расширенную индексацию в матрице - https://docs.scipy.org/doc/numpy/reference/arrays.indexing.html

Это работает, как и ожидалось, возвращает всю матрицу, v

import numpy as np
v = np.reshape(np.arange(0,9), (3,3))
v[np.asarray([0,1,2])[:,np.newaxis], np.asarray([0,1,2])]

Использование логической индексации также работает как ожидалось:

v[np.asarray([0,1,2])[:,np.newaxis], np.asarray([True, True, True])]

Удивительно (для меня, по крайней мере) это ошибки при переключении порядка индексных векторов?

v[np.asarray([True, True, True])[:,np.newaxis], np.asarray([0,1,2])]

Или если оба вектора булевы

v[np.asarray([True, True, True])[:,np.newaxis], np.asarray([True, True, True])]

С ошибкой «*** IndexError: слишком много индексов для массива». Я ожидал, что третий и четвертый примеры будут работать так же, как первый и второй. Чего мне не хватает?

1 Ответ

1 голос
/ 08 ноября 2019

https://docs.scipy.org/doc/numpy/reference/arrays.indexing.html#boolean-array-indexing

последняя часть этого раздела логической индексации говорит, что вам нужно использовать np.ix_ для генерации соответствующих индексов. Он преобразует логическое значение в эквивалентные ненулевые индексы. Вещание не работает с логическими массивами

In [48]: np.ix_(np.asarray([True, True, True]), np.asarray([0,1,2]))            
Out[48]: 
(array([[0],
        [1],
        [2]]), array([[0, 1, 2]]))

ix_ генерирует правильные индексы массива для индексации блока:

In [50]: v[np.ix_(np.asarray([True, True, True]), np.asarray([0,1,2]))]         
Out[50]: 
array([[0, 1, 2],
       [3, 4, 5],
       [6, 7, 8]])

Те же массивы без ix выбирают диагональ:

In [51]: v[np.asarray([True, True, True]), np.asarray([0,1,2])]                 
Out[51]: array([0, 4, 8])

Если логическое индексирование выполняется с какой-либо формой np.where/nonzero, возможно, что этот результат 2d nonzero приведет к ошибке индексации. Но это происходит в скомпилированном коде, поэтому трудно отследить детали:

In [53]: np.asarray([True, True, True])[:,np.newaxis].nonzero()                 
Out[53]: (array([0, 1, 2]), array([0, 0, 0]))

Мы можем индексировать с помощью логического значения, которое соответствует v по форме, но результат равен 1d:

In [66]: np.array([True,True,True])[:,None].repeat(3,1)                         
Out[66]: 
array([[ True,  True,  True],
       [ True,  True,  True],
       [ True,  True,  True]])
In [67]: v[_]                                                                   
Out[67]: array([0, 1, 2, 3, 4, 5, 6, 7, 8])
...