Код для diag_indices
прост, настолько прост, что я никогда его не использовал:
idx = arange(n)
return (idx,) * ndim
In [68]: np.diag_indices(4,2)
Out[68]: (array([0, 1, 2, 3]), array([0, 1, 2, 3]))
Он просто возвращает кортеж массивов, arange
повторяется n
раз. Это полезно для индексации главной диагонали квадратной матрицы, например
In [69]: arr = np.arange(16).reshape(4,4)
In [70]: arr
Out[70]:
array([[ 0, 1, 2, 3],
[ 4, 5, 6, 7],
[ 8, 9, 10, 11],
[12, 13, 14, 15]])
In [71]: arr[np.diag_indices(4,2)]
Out[71]: array([ 0, 5, 10, 15])
Приложение представляет собой прямую индексацию с двумя массивами, которые совпадают по форме.
Это работает с другими формами - если они большие enogh.
np.diag
, примененный к тому же массиву, делает то же самое:
In [72]: np.diag(arr)
Out[72]: array([ 0, 5, 10, 15])
, но также позволяет смещение:
In [73]: np.diag(arr, 1)
Out[73]: array([ 1, 6, 11])
== =
Индексирование с помощью diag_indices
действительно позволяет нам изменить эту диагональ:
In [78]: arr[np.diag_indices(4,2)] += 10
In [79]: arr
Out[79]:
array([[10, 1, 2, 3],
[ 4, 15, 6, 7],
[ 8, 9, 20, 11],
[12, 13, 14, 25]])
====
Но нам необязательно использовать diag_indices
для генерации желаемых массивов индексации:
In [80]: arr = np.arange(1,7).reshape(3,2)
In [81]: arr
Out[81]:
array([[1, 2],
[3, 4],
[5, 6]])
выбор значений из первых 2 строк и столбцов:
In [82]: arr[np.arange(2), np.arange(2)]
Out[82]: array([1, 4])
In [83]: arr[np.arange(2), np.arange(2)] += 10
In [84]: arr
Out[84]:
array([[11, 2],
[ 3, 14],
[ 5, 6]])
и для разностного выбора строк:
In [85]: arr[np.arange(1,3), np.arange(2)] += 20
In [86]: arr
Out[86]:
array([[11, 2],
[23, 14],
[ 5, 26]])
Соответствующий раздел документации по advanced indexing
с целочисленными массивами: https://numpy.org/doc/stable/reference/arrays.indexing.html#purely -integer-array-indexing