У меня есть четыре матрицы, частично созданные друг от друга:
A
- это трехмерная матрица, которая представляет собой стопку изображений в градациях серого и имеет форму (n, h, w)
B
- это трехмерная матрица, которая также представляет стопку изображений, где каждый срез индивидуально рассчитывается из соответствующего среза в A
и также имеет форму (n, h, w)
C
- это двумерная матрица , содержащий индекс с максимальным значением B
в направлении z и имеющий форму (h, w)
D
представляет собой 2D-матрицу, где значение из A копируется из определенного среза, который является обозначается значением в C
в позиции (x, y)
.
Минимальный пример, реализованный с помощью циклов, будет выглядеть следующим образом:
import numpy as np
A = np.random.randint(0, 255, size=(3, 4, 5))
B = np.random.randint(0, 255, size=(3, 4, 5))
C = np.argmax(B, axis=0)
D = np.zeros(C.shape, dtype=int)
for y in range(C.shape[0]):
for x in range(C.shape[1]):
D[y, x] = A[C[y, x], y, x]
> A
array([[[ 24, 84, 155, 8, 147],
[ 25, 4, 49, 195, 57],
[ 93, 76, 233, 83, 177],
[ 70, 211, 201, 132, 239]],
[[177, 144, 247, 251, 207],
[242, 148, 28, 40, 105],
[181, 28, 132, 94, 196],
[166, 121, 72, 14, 14]],
[[ 55, 254, 140, 142, 14],
[112, 28, 85, 112, 145],
[ 16, 72, 16, 248, 179],
[160, 235, 225, 14, 211]]])
> B
array([[[246, 14, 55, 163, 161],
[ 3, 152, 128, 104, 203],
[ 43, 145, 59, 169, 242],
[106, 169, 31, 222, 240]],
[[ 41, 26, 239, 25, 65],
[ 47, 252, 205, 210, 138],
[194, 64, 135, 127, 101],
[ 63, 208, 179, 137, 59]],
[[112, 156, 183, 23, 253],
[ 35, 6, 233, 42, 100],
[ 66, 119, 102, 217, 64],
[ 82, 67, 135, 6, 8]]])
> C
array([[0, 2, 1, 0, 2],
[1, 1, 2, 1, 0],
[1, 0, 1, 2, 0],
[0, 1, 1, 0, 0]])
> D
array([[ 24, 254, 247, 8, 14],
[242, 148, 85, 40, 57],
[181, 76, 132, 248, 177],
[ 70, 121, 72, 132, 239]])
Мой вопрос: как нарезать ломтиками A
с C
, эффективно устраняя вложенные циклы for? Моя первоначальная идея состояла в том, чтобы расширить C
до трехмерной логической маски, где только позиции [c, y, x]
установлены на True
, а затем просто умножить ее поэлементно на A
и взять сумму по оси z. Но я не могу представить себе реализацию Pythonesque без циклов (и мне, вероятно, больше не нужно было бы создавать булеву маску, если бы я знал, как это написать).
Ближайшая уже реализованная функция I найдено np.choose () , но для C требуется всего 32 элемента.