Создайте отличительный массив:
In [13]: a = np.arange(25).reshape(5,5)
In [14]: dim1 = np.arange(5)[:,None]
In [15]: dim2 = np.eye(5,5).astype(int)
Посмотрите, как эти два массива вещают друг с другом:
In [16]: np.broadcast_arrays(dim1, dim2)
Out[16]:
[array([[0, 0, 0, 0, 0],
[1, 1, 1, 1, 1],
[2, 2, 2, 2, 2],
[3, 3, 3, 3, 3],
[4, 4, 4, 4, 4]]),
array([[1, 0, 0, 0, 0],
[0, 1, 0, 0, 0],
[0, 0, 1, 0, 0],
[0, 0, 0, 1, 0],
[0, 0, 0, 0, 1]])]
Возвращенный массив соответствует этим двум по форме, с элементами, выбранными изa
путем сопряжения отдельных элементов от каждого.
In [17]: a[dim1, dim2]
Out[17]:
array([[ 1, 0, 0, 0, 0],
[ 5, 6, 5, 5, 5],
[10, 10, 11, 10, 10],
[15, 15, 15, 16, 15],
[20, 20, 20, 20, 21]])
Для каждой строки, индексированной dim1
, он выбирает элемент из столбца 0 или 1 в зависимости от значения dim2
:
In [21]: a[0, dim2[0,:]]
Out[21]: array([1, 0, 0, 0, 0])
In [22]: a[3, dim2[3,:]]
Out[22]: array([15, 15, 15, 16, 15])
Если я изменю dim2
на «диагональ»
In [25]: dim2 = np.diag(np.arange(5))
In [26]: dim2
Out[26]:
array([[0, 0, 0, 0, 0],
[0, 1, 0, 0, 0],
[0, 0, 2, 0, 0],
[0, 0, 0, 3, 0],
[0, 0, 0, 0, 4]])
In [27]: a[dim1, dim2]
Out[27]:
array([[ 0, 0, 0, 0, 0],
[ 5, 6, 5, 5, 5],
[10, 10, 12, 10, 10],
[15, 15, 15, 18, 15],
[20, 20, 20, 20, 24]])
Теперь большинство значений a[:,0]
, но диагонали a[i,i]
.
Это индексирование ничем не отличается от индексирования с помощью 1d-массивов, как в
In [28]: a[np.arange(5), np.arange(5)]
Out[28]: array([ 0, 6, 12, 18, 24])
a[0,0], a[1,1], a[2,2], ...
Еще один пример, который можно объяснить, передавая два массива друг против друга.При этом выбираются все элементы, такие же как a[:,:]
, за исключением того, что это копия, а не представление:
In [29]: a[np.arange(5)[:,None], np.arange(5)[None,:]]
Out[29]:
array([[ 0, 1, 2, 3, 4],
[ 5, 6, 7, 8, 9],
[10, 11, 12, 13, 14],
[15, 16, 17, 18, 19],
[20, 21, 22, 23, 24]])