Я не могу думать о том, как работать это в N измерениях еще, но
здесь версия 2D:
>>> a = np.random.standard_normal(size=(2,5))
>>> a
array([[ 0.72322499, -0.05376714, -0.28316358, 1.43025844, -0.90814293],
[ 0.7459107 , 0.43020728, 0.05411805, -0.32813465, 2.38829386]])
>>> i = np.array([[0,1,2,4,3],[0,1,2,3,4]])
>>> a[np.arange(a.shape[0])[:,np.newaxis],i]
array([[ 0.72322499, -0.05376714, -0.28316358, -0.90814293, 1.43025844],
[ 0.7459107 , 0.43020728, 0.05411805, -0.32813465, 2.38829386]])
Здесь N-мерная версия:
>>> a[list(np.ogrid[[slice(x) for x in a.shape]][:-1])+[i]]
Вот как это работает:
Хорошо, давайте начнем с 3-мерного массива для иллюстрации.
>>> import numpy as np
>>> a = np.arange(24).reshape((2,3,4))
>>> 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]]])
Вы можете получить доступ к элементам этого массива, указав индекс по каждой оси следующим образом:
>>> a[0,1,2]
6
Это эквивалентно a[0][1][2]
, который, как вы бы получить доступ и тот же элемент, если бы мы имели дело с вместо массива.
Numpy позволяет получить даже любителю, когда нарезка массивы:
>>> a[[0,1],[1,1],[2,2]]
array([ 6, 18])
>>> a[[0,1],[1,2],[2,2]]
array([ 6, 22])
Эти примеры были бы эквивалентны [a[0][1][2],a[1][1][2]]
и [a[0][1][2],a[1][2][2]]
, если мы имеем дело со списками.
Вы можете даже отказаться от повторяющихся индексов, и numpy будет определять, что вы хотите. Например, приведенные выше примеры можно было бы то же самое написано:
>>> a[[0,1],1,2]
array([ 6, 18])
>>> a[[0,1],[1,2],2]
array([ 6, 22])
Форма массива (или список) вы отрезаете с в каждом измерении влияет только на форму возвращаемого массива. Другими словами, numpy не заботится о том, чтобы вы пытались индексировать массив массивом формы (2,3,4)
, когда он вытаскивает значения, за исключением того, что он вернет вам массив формы (2,3,4)
.Например:
>>> a[[[0,0],[0,0]],[[0,0],[0,0]],[[0,0],[0,0]]]
array([[0, 0],
[0, 0]])
В этом случае мы захватывая один и тот же элемент, a[0,0,0]
снова и снова, но NumPy возвращает массив с одной и той же форме, как мы прошли в
Ok, на. твоя проблема. Вы хотите проиндексировать массив вдоль последней оси с числами в вашем массиве index
. Итак, для примера в вашем вопросе вы хотели бы [[a[0,0],a[0,1],a[0,2],a[0,4],a[0,3]],a[1,0],a[1,1],...
Тот факт, что ваш индексный массив является многомерным, как я уже говорил ранее, не говорит о том, что вы хотите извлечь из этих индексов ничего лишнего; он просто определяет форму выходного массива. Итак, в вашем примере вам нужно указать numpy, что первые 5 значений нужно вытащить из a[0]
, а последние 5 из a[1]
. Легко!
>>> a[[[0]*5,[1]*5],index]
Это усложняется в N измерениях, но давайте сделаем это для 3 одномерного массива a
я определенным образом выше. Предположим, что мы имеем следующий индексный массив:
>>> i = np.array(range(4)[::-1]*6).reshape(a.shape)
>>> i
array([[[3, 2, 1, 0],
[3, 2, 1, 0],
[3, 2, 1, 0]],
[[3, 2, 1, 0],
[3, 2, 1, 0],
[3, 2, 1, 0]]])
Таким образом, эти значения являются значениями для индексов вдоль последней оси. Нам нужно указать numpy, какие индексы вдоль первой и второй осей должны быть взяты из этих чисел; то есть мы должны сказать NumPy, что индексы для первой оси являются:
i1 = [[[0, 0, 0, 0],
[0, 0, 0, 0],
[0, 0, 0, 0]],
[[1, 1, 1, 1],
[1, 1, 1, 1],
[1, 1, 1, 1]]]
и индексы для второй оси являются:
i2 = [[[0, 0, 0, 0],
[1, 1, 1, 1],
[2, 2, 2, 2]],
[[0, 0, 0, 0],
[1, 1, 1, 1],
[2, 2, 2, 2]]]
Тогда мы можем просто сделать:
>>> a[i1,i2,i]
array([[[ 3, 2, 1, 0],
[ 7, 6, 5, 4],
[11, 10, 9, 8]],
[[15, 14, 13, 12],
[19, 18, 17, 16],
[23, 22, 21, 20]]])
Удобная функция numpy, которая генерирует i1
и i2
, называется np.mgrid
. Я использую np.ogrid
в своем ответе, который в этом случае эквивалентен из-за магии numpy, о которой я говорил ранее.
Надеюсь, что это поможет!
Итак, если я правильно понимаю, вы хотите переупорядочить каждую «строку» «a1», используя индексы в каждой строке «index»? другими словами a1.take (index), если вы были 1D, но делаете это для каждой строки? –
yup. Поэтому закажите первую строку a1 по первой строке индекса и второй строке a1 по второй строке индекса. А так как a1 растет до размера n, то индекс также будет. –