Python: Numpy Умножьте каждую строку массива на каждую строку другого массива - PullRequest
2 голосов
/ 24 апреля 2019

Я знаю, что были некоторые вопросы по этому поводу, и это должно быть возможно с вещанием.Но почему-то я не совсем понимаю, как вещание работает с добавлением дополнительной оси.Существует похожий вопрос, где каждый столбец одного массива умножается на каждый столбец другого массива: Умножьте каждый столбец на каждый столбец .В моем случае я хочу умножить каждую строку 2-мерных массивов друг на друга

У меня просто есть трехмерный массив, созданный в виде треугольной матрицы:

matrix = np.tril(np.ones((3,3,3),dtype='bool'))

Для упрощения просто посмотрите напервые два массива:

matrix[:2]

[[[ True False False]
  [ True  True False]
  [ True  True  True]]

 [[ True False False]
  [ True  True False]
  [ True  True  True]]]

Это должно стать:

[[[ True False False]
  [ True False False]
  [ True False False]]#First row of first array multiplied with each row of second array

 [[ True False False]
  [ True  True False]
  [ True  True False]]#Second row of first array multiplied with each row of second array

 [[ True False False]
  [ True  True False]
  [ True  True  True]]]#Third row of first array multiplied with each row of third array

Я могу добиться этого с помощью

matrix[0][None,...]*matrix[1][:,None])

Но как я могу сделать это для всей матрицыбез зацикливания и как работает трансляция?Это должно привести к созданию 3d-массива с 9-ю 2d-массивами.

EDIT

Для подробного объяснения, что это такое и как должен выглядеть результирующий массив.У меня есть несколько категорий, скажем, 3. Все эти 3 категории могут иметь 4 состояния, каждое состояние состоит, например, из массива bool с 4 значениями bool (также может быть 10 категорий со 100 состояниями с 100 значениями bool).Теперь я хочу получить результирующий массив, который я могу индексировать.Так, например, я хочу вывод умноженных состояний всех 3 категорий и его значения 3.Я бы индексировал его с помощью resultArray [0,0,0,1] для второго значения bool умножения.

С массивом 3x4x4 (3 категории, 4 состояния, 4 значения bool), но для визуализации с числамиэто будет выглядеть следующим образом:

cats = 3
values = 4

matrix = np.arange(48).reshape(cats,values,values)
matrix.shape


totalArray=np.zeros((values,values,values,values))
for row1 in range(len(matrix[0])):
    for row2 in range(len(matrix[1])):
        for row3 in range(len(matrix[2])):
            totalArray[row1,row2,row3] = matrix[0][row1]*matrix[1][row2]*matrix[2][row3]

print(matrix)            
print(totalArray)

Выход

[[[ 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]
  [36 37 38 39]
  [40 41 42 43]
  [44 45 46 47]]]
[[[[    0.   561.  1224.  1995.]
   [    0.   629.  1368.  2223.]
   [    0.   697.  1512.  2451.]
   [    0.   765.  1656.  2679.]]

  [[    0.   693.  1496.  2415.]
   [    0.   777.  1672.  2691.]
   [    0.   861.  1848.  2967.]
   [    0.   945.  2024.  3243.]]

  [[    0.   825.  1768.  2835.]
   [    0.   925.  1976.  3159.]
   [    0.  1025.  2184.  3483.]
   [    0.  1125.  2392.  3807.]]

  [[    0.   957.  2040.  3255.]
   [    0.  1073.  2280.  3627.]
   [    0.  1189.  2520.  3999.]
   [    0.  1305.  2760.  4371.]]]


 [[[ 2048.  2805.  3672.  4655.]
   [ 2304.  3145.  4104.  5187.]
   [ 2560.  3485.  4536.  5719.]
   [ 2816.  3825.  4968.  6251.]]

  [[ 2560.  3465.  4488.  5635.]
   [ 2880.  3885.  5016.  6279.]
   [ 3200.  4305.  5544.  6923.]
   [ 3520.  4725.  6072.  7567.]]

  [[ 3072.  4125.  5304.  6615.]
   [ 3456.  4625.  5928.  7371.]
   [ 3840.  5125.  6552.  8127.]
   [ 4224.  5625.  7176.  8883.]]

  [[ 3584.  4785.  6120.  7595.]
   [ 4032.  5365.  6840.  8463.]
   [ 4480.  5945.  7560.  9331.]
   [ 4928.  6525.  8280. 10199.]]]


 [[[ 4096.  5049.  6120.  7315.]
   [ 4608.  5661.  6840.  8151.]
   [ 5120.  6273.  7560.  8987.]
   [ 5632.  6885.  8280.  9823.]]

  [[ 5120.  6237.  7480.  8855.]
   [ 5760.  6993.  8360.  9867.]
   [ 6400.  7749.  9240. 10879.]
   [ 7040.  8505. 10120. 11891.]]

  [[ 6144.  7425.  8840. 10395.]
   [ 6912.  8325.  9880. 11583.]
   [ 7680.  9225. 10920. 12771.]
   [ 8448. 10125. 11960. 13959.]]

  [[ 7168.  8613. 10200. 11935.]
   [ 8064.  9657. 11400. 13299.]
   [ 8960. 10701. 12600. 14663.]
   [ 9856. 11745. 13800. 16027.]]]


 [[[ 6144.  7293.  8568.  9975.]
   [ 6912.  8177.  9576. 11115.]
   [ 7680.  9061. 10584. 12255.]
   [ 8448.  9945. 11592. 13395.]]

  [[ 7680.  9009. 10472. 12075.]
   [ 8640. 10101. 11704. 13455.]
   [ 9600. 11193. 12936. 14835.]
   [10560. 12285. 14168. 16215.]]

  [[ 9216. 10725. 12376. 14175.]
   [10368. 12025. 13832. 15795.]
   [11520. 13325. 15288. 17415.]
   [12672. 14625. 16744. 19035.]]

  [[10752. 12441. 14280. 16275.]
   [12096. 13949. 15960. 18135.]
   [13440. 15457. 17640. 19995.]
   [14784. 16965. 19320. 21855.]]]]

Дело в том, что массивы категорий всегда равны треугольной матрице.Возможно, было бы достаточно иметь один треугольный массив и умножить его.В конце я хочу дать массив списков индексов, таких как [[0,0,0,1], [0,0,0,2]], чтобы получить два значения bool для этого умножения.

1 Ответ

1 голос
/ 24 апреля 2019

Вам нужно разложить вторую ось, чтобы создать две 4D версии и позволить им размножаться друг против друга -

matrix[:,None,:,:]*matrix[:,:,None,:]

Или просто -

matrix[:,None]*matrix[...,None,:]

Внешняя работа

Пояснение к схеме:

Мы собираемся выполнить внешнее поэлементное умножение друг на друга вдоль второй оси. Итак, нам нужно расширить оси и создать две версии 4D-массива так, чтобы в другой версии был синглтон (ось с длиной = 1), соответствующий версии с полной длиной оси. Мы делаем это расширение измерения с np.newaxis/None.

Рассмотрим двумерный случай формы (3,5):

matrix : 3 x 5

Давайте сделаем внешне-поэлементное умножение вдоль второй оси. Таким образом, расширение массивов будет -

matrix-version1 : 3 x 1 x 5
matrix-version2 : 3 x 5 x 1

Аналогично, для выполнения внешне-поэлементного умножения вдоль первой оси, это будет -

matrix-version1 : 1 x 3 x 5
matrix-version2 : 3 x 1 x 5

Таким образом, распространяя это на наш 3D случай для умножения по внешнему элементу вдоль второй оси и принимая форму (m,n,r), это будет -

matrix-version1 : m x 1 x n x r # [:,None,:,:]
matrix-version2 : m x n x 1 x r # [:,:,None,:]

Следовательно, после поэлементного умножения получается:

output          : m x n x n x r
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...