numpy.ravel_multi_index
numpy.ravel_multi_index(multi_index, dims, mode='raise', order='C')
Функция ravel_multi_index() преобразует кортеж массивов индексов в плоский массив индексов.
Данная функция позволяет получить индексы элементов многомерного массива в его сжатой до одной оси копии, на основе их индексов в исходном массиве.
-
- multi_index - кортеж массивов NumPy или массивоподобных объектов.
- Кортеж массивов индексов, в котором один массив индексирует соответствующую ось исходного массива.
- dims - кортеж целых чисел.
-
Определяет форму массива, который индексируется массивами из
multi_index
. - mode - {'raise', 'wrap', 'clip'} (необязательный параметр).
-
Определяет метод обработки индексов, которые выходят за пределы формы исходного массива. Если указан один режим, то он применяется ко всем массивам в
multi_index
, но можно указать кортеж режимов аналогичной длинны, что бы обрабатывать каждый массив отдельно.'raise'
- вызывать исключение (по умолчанию);'wrap'
- обогнуть вокруг оси, т.е. циклически сместиться по ней;'clip'
- обрезает до диапазона индексов исходного массива, причем отрицательные индексы обрезаются до 0.
- order - {'C', 'F'} (необязательный параметр).
- Определяет то каким образом рассматривать исходный массив, если 'C' - то это стандартный (уже привычный) массив данные в котором хранятся в строковом порядке (C-стиле), если 'F' - то это массив в столбчатом стиле Fortran.
-
- ndarray - массив NumPy
- массив индексов элементов исходного массива в его сжатой до одной оси копии.
Примеры
Допустим у нас есть двумерный массив и мы индексируем его следующим образом:
>>> import numpy as np
>>>
>>> a = np.arange(0, 24, 2).reshape(3, 4)
>>> a
array([[ 0, 2, 4, 6],
[ 8, 10, 12, 14],
[16, 18, 20, 22]])
>>>
>>> a[[0, 1, 2], [3, 2, 1]]
array([ 6, 12, 18])
Теперь, представим, что по какой то причине этот массив стал плоским:
>>> b = a.ravel()
>>> b
array([ 0, 2, 4, ..., 18, 20, 22])
Какими должны быть индексы элементов нового, плоского массива, что бы вытащить из него те же самые элементы? Именно на этот вопрос и отвечает функция ravel_multi_index
:
>>> np.ravel_multi_index(([0, 1, 2], [3, 2, 1]), (3, 4))
array([3, 6, 9], dtype=int32)
>>>
>>> b[[3, 6, 9]]
array([ 6, 12, 18])
Можно подумать, что каждый массив индексов должен быть одномерным, но это может быть любой допустимый массив индексов:
>>> a[[[1, 2], [0, 1]], [1, 2]]
array([[10, 20],
[ 2, 12]])
>>>
>>> np.ravel_multi_index(([[1, 2], [0, 1]], [1, 2]), (3, 4))
array([[ 5, 10],
[ 1, 6]], dtype=int32)
>>>
>>> b[[5, 10, 1, 6]]
array([10, 20, 2, 12])
>>>
>>> b[np.ravel_multi_index(([[1, 2], [0, 1]], [1, 2]), (3, 4))]
array([[10, 20],
[ 2, 12]])
Мы так же можем узнать индекс всего одного элемента:
>>> np.ravel_multi_index((1, 3), (3, 4))
7
>>>
>>> a[1, 3]
14
>>>
>>> b[7]
14
Очень редко, но все же приходится иметь дело с Fortran кодом, в котором массивы хранятся в столбчатом стиле. А в этом стиле строки являются столбцами а столбцы строками. Что бы индексировать такие массивы достаточно установить соответствующий флаг в параметре order
:
>>> np.ravel_multi_index(([0, 1, 2], [3, 2, 1]), (3, 4))
array([3, 6, 9], dtype=int32)
>>>
>>> np.ravel_multi_index(([0, 1, 2], [3, 2, 1]), (3, 4), order = 'F')
array([9, 7, 5], dtype=int32)
Случаи, в которых значения в массивах индексов выходят за пределы исходного индекса могут быть обработаны без вызова исключения (ошибки), для этого достаточно указать режим их обработки в параметре mode
:
>>> np.ravel_multi_index(([1, 3], [1, 2]), (3, 4), mode = 'wrap')
array([5, 2], dtype=int32)
>>>
>>> np.ravel_multi_index(([1, 3], [1, 2]), (3, 4), mode = 'clip')
array([ 5, 10], dtype=int32)