numpy.indices

numpy.indices(dimensions, dtype = <class 'int'>)

Функция indices() возвращает координатную сетку для пространства заданной размерности и заданного размера.

Параметры:
dimensions - кортеж целых положительных чисел.
Определяет количество и длину измерений возвращаемой координатной сетки.
dtype - тип данных NumPy (необязательный параметр).
Определяет тип данных возвращаемого массива.
Возвращает:
ndarray - массив NumPy
массив с координатной сеткой для указанного количества измерений и их длины.
Смотрите так же:
meshgrid, ogrid, mgrid

Замечание

Форма возвращаемого массива определяется соотношением np.indices(dimensions).shape = len(dimensions) + dimensions.



Примеры

По сути, данная функция возвращает массив в котором каждый подмассив соответсвует оси указанной в параметре dimensions, а изменение его элементов увеличивается от 0 до указанного числа только в направлении этой оси. Проще понять на примерах.

Вот координатная сетка для двумерного пространства:

>>> import numpy as np
>>> 
>>> np.indices((4, 6))
array([[[0, 0, 0, 0, 0, 0],
        [1, 1, 1, 1, 1, 1],
        [2, 2, 2, 2, 2, 2],
        [3, 3, 3, 3, 3, 3]],

       [[0, 1, 2, 3, 4, 5],
        [0, 1, 2, 3, 4, 5],
        [0, 1, 2, 3, 4, 5],
        [0, 1, 2, 3, 4, 5]]])

А вот и для трехмерного:

>>> np.indices((2, 3, 4))
array([[[[0, 0, 0, 0],
         [0, 0, 0, 0],
         [0, 0, 0, 0]],

        [[1, 1, 1, 1],
         [1, 1, 1, 1],
         [1, 1, 1, 1]]],


       [[[0, 0, 0, 0],
         [1, 1, 1, 1],
         [2, 2, 2, 2]],

        [[0, 0, 0, 0],
         [1, 1, 1, 1],
         [2, 2, 2, 2]]],


       [[[0, 1, 2, 3],
         [0, 1, 2, 3],
         [0, 1, 2, 3]],

        [[0, 1, 2, 3],
         [0, 1, 2, 3],
         [0, 1, 2, 3]]]])

Как это выглядит мы теперь более-менее представляем. Теперь собственно о том зачем все это надо. С одной стороны это можно использовать для табулирования функций:

>>> x, y = np.indices((5, 5))
>>> f = x**2 + y**2
>>> f
array([[ 0,  1,  4,  9, 16],
       [ 1,  2,  5, 10, 17],
       [ 4,  5,  8, 13, 20],
       [ 9, 10, 13, 18, 25],
       [16, 17, 20, 25, 32]], dtype=int32)

Однако, для табулирования функций, вместо indices, гораздо удобнее использовать meshgrid, ogrid или mgrid.

Еще одно применение для данной функции - это индексирование других массивов:

>>> a = np.arange(36).reshape(6, 6)
>>> a
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, 25, 26, 27, 28, 29],
       [30, 31, 32, 33, 34, 35]])
>>> 
>>> row, col = np.indices((3, 4))
>>> a[row, col]
array([[ 0,  1,  2,  3],
       [ 6,  7,  8,  9],
       [12, 13, 14, 15]])

Можем даже пробежаться "окном" по массиву. Для экономии бесценного бесконечного места веб-страницы (сарказм) я не буду приводить эту "пробежку" целиком, а лишь покажу, что это "окно" действительно очень легко перемещать, до чего вы в принципе и сами прекрасно догадались (не сарказм):

>>> a[row, col]
array([[ 0,  1,  2,  3],
       [ 6,  7,  8,  9],
       [12, 13, 14, 15]])
>>> 
>>> a[row, col + 1]
array([[ 1,  2,  3,  4],
       [ 7,  8,  9, 10],
       [13, 14, 15, 16]])
>>> 
>>> a[row, col + 2]
array([[ 2,  3,  4,  5],
       [ 8,  9, 10, 11],
       [14, 15, 16, 17]])
>>> 
>>> a[row + 1, col + 1]
array([[ 7,  8,  9, 10],
       [13, 14, 15, 16],
       [19, 20, 21, 22]])
>>> 
>>> a[row - 1, col - 1]
array([[35, 30, 31, 32],
       [ 5,  0,  1,  2],
       [11,  6,  7,  8]])

Хотя, проще и наверняка быстрее было бы извлекать эти "окна" с помощью индексных выражений, но это не всегда возможно, например:

>>> a[:3, :4]    #  равносильно a[row, col]
array([[ 0,  1,  2,  3],
       [ 6,  7,  8,  9],
       [12, 13, 14, 15]])
>>> 
>>> 
>>> a[1:4, 1:5]    #  равносильно a[row + 1, col + 1]
array([[ 7,  8,  9, 10],
       [13, 14, 15, 16],
       [19, 20, 21, 22]])

Но вот как получить с помощью индексного выражения (среза) что-то вроде:

>>> a[row - 2, col - 1]
array([[29, 24, 25, 26],
       [35, 30, 31, 32],
       [ 5,  0,  1,  2]])

То есть получить циклический сдвиг "окна" по массиву с помощью np.indices(), намного проще, чем что-то изобретать с индексными выражениями.

Параметр dtype, позволяет задать необходимый тип данных получаемого массива, который по умолчанию равен int:

>>> np.indices((2, 3), dtype = np.float)
array([[[0., 0., 0.],
        [1., 1., 1.]],

       [[0., 1., 2.],
        [0., 1., 2.]]])
>>> 
>>> 
>>> np.indices((2, 3), dtype = np.complex)
array([[[0.+0.j, 0.+0.j, 0.+0.j],
        [1.+0.j, 1.+0.j, 1.+0.j]],

       [[0.+0.j, 1.+0.j, 2.+0.j],
        [0.+0.j, 1.+0.j, 2.+0.j]]])