Разрезание массива рангов 2 с использованием двух объектов диапазона - PullRequest
0 голосов
/ 11 марта 2019

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

A = rand(3,3)
assert(allclose(A[0:3, 0:3], A))

С другой стороны, если я создаю срезы заранее, индексирование не работает должным образом (по крайней мере, с точки зрения пользователя octave / matlab, где оба метода дают одинаковый результат):

A = rand(3,3)
i = range(0,3)
j = range(0,3)
assert(allclose(A[i, j], A))
# AssertionError

Почему эти методы дают разные результаты?

1 Ответ

0 голосов
/ 12 марта 2019

Почему вы ожидаете, что они сделают то же самое?numpy отличается от MATLAB этим видом индексации.

In [6]: arr = np.arange(9).reshape(3,3)

In [7]: arr[range(3),range(3)]
Out[7]: array([0, 4, 8])

С диапазоном (или списком или массивом с одинаковыми значениями) он возвращает массив 1d, в данном случае диагональ2d массив.Эта индексация выбирает набор точек, а не блок.

В numpy, если вы хотите получить двумерный результат с «расширенной индексацией», вам нужно создать пару массивов индексации, которые вместе передают правильную форму:

In [8]: arr[np.arange(3)[:,None],range(3)]
Out[8]: 
array([[0, 1, 2],
       [3, 4, 5],
       [6, 7, 8]])

В MATLAB / octave легко выбрать блок, но гораздо сложнее выделить отдельные элементы.

arr(sub2ind([3,3],[1,2,3],[1,2,3]))

В общем, для понимания numpy расширенного индексирования вам необходимопонимать вещание - это относится как к индексированию, так и к математическим операциям, таким как сложение.

...