Я пытаюсь извлечь и выполнить математику для подмножества одного массива numpy, который имеет форму (3,32), подмножество данных, которые я пытаюсь извлечь, имеет форму (3,9) и диапазоны этого данные исходят из индексов, содержащихся в другом размере массива (3). Например, у меня есть набор данных из трех каналов, работающих во временной области, и я извлекаю индекс максимального значения каждого канала в массив.
a = np.random.randint(20,size = (3,32))
a
array([[18, 3, 10, 6, 12, 1, 10, 8, 4, 11, 13, 14, 9, 9, 10, 2,
9, 0, 0, 16, 14, 19, 1, 19, 14, 19, 19, 2, 14, 0, 4, 18],
[ 9, 19, 2, 12, 0, 14, 18, 7, 3, 0, 7, 3, 12, 19, 4, 2,
5, 9, 2, 11, 15, 19, 16, 17, 3, 4, 17, 5, 6, 1, 2, 17],
[ 0, 11, 18, 8, 9, 2, 9, 15, 9, 6, 0, 8, 9, 16, 9, 6,
1, 19, 1, 9, 12, 8, 0, 0, 7, 15, 3, 14, 15, 8, 10, 19]])
b = np.argmax(a,1)
b
array([21, 1, 17], dtype=int64)
моя цель на данный момент состоит в том, чтобы получить новый массив, состоящий из трех значений каждого из указанных индексов. Например, я хотел бы извлечь:
[21,22,23] from a[0]
[1,2,3] from a[1]
[17,18,19] from a[2]
все в новый массив размера [3,3]
Мне уже удалось добиться этого с помощью циклов, но я подозреваю, что есть более эффективный способ получения этого результата без циклов (скорость в этом приложении немного проблематична). Я смог добиться аналогичного результата, вручную заполнив меньшую матрицу...
c = np.asarray([[1,2,3],[2,3,4],[3,4,5]])
a[np.arange(3)[:,None],c]
array([[ 3, 10, 6],
[ 2, 12, 0],
[ 8, 9, 2]])
Однако, учитывая динамическую природу этого приложения, я хотел бы написать это таким образом, чтобы его можно было динамически масштабировать (диапазон индексов до 9 значений за пределами корневого индекса и т. д.). Я просто не знаю, есть ли такой способ сделать это. Я использовал синтаксис, подобный следующему, чтобы разрезать массив...
a[np.arange(3)[:,None],b[:]:(b[:] + 2)]
что приводит к сообщениям об ошибках в характере...
builtins.TypeError: only integer scalar arrays can be converted to a scalar index
Да, я считал, что должен указать, что диапазон никогда не будет превышать границы массива, учитывая характер приложения (в реальном приложении максимальные индексы всегда равны 10 +/- 1)
В принятом решении используйте b
вместо idx
.
Поскольку вы говорите, что не можете переполниться, это становится намного проще. В общем, поскольку у вас есть начальные индексы, вы можете использовать базовую трансляцию для создания массива форм (n, 3)
с вашими индексами и использовать take_along_axis
для извлечения этих элементов из исходного массива.
np.take_along_axis(a, b[:, None] + np.arange(3), axis=1)
array([[19, 1, 19],
[19, 2, 12],
[19, 1, 9]])
Что делать, если в строке
a
не осталось 3 значений? Например, что, если бы максимум был в индексе31
?