умножение больших 2D numpy массивов - PullRequest
1 голос
/ 06 апреля 2020

Я хотел бы умножить следующие матрицы (используя numpy) наиболее эффективным способом.

Это код для матриц:

a = np.array([[1, 5], [2, 6], [3, 7], [4, 8]])
m = np.array([[1, 0, 0, 1], [1, 0, 1, 0], [0, 1, 0, 1], [0, 1, 1, 1]])

Это матрицы лучше визуализировать:

a:
[[1 5]
 [2 6]
 [3 7]
 [4 8]]

m:
[[1 0 0 1]
 [1 0 1 0]
 [0 1 0 1]
 [0 1 1 1]]

Я хочу умножить a на (первый столбец матрицы m), вот так

   a    m[:,0]       x0

[[1 5]   [[1]      [[1 5]
 [2 6] *  [1]   =   [2 6]    
 [3 7]    [0]       [0 0]
 [4 8]]   [0]]      [0 0]

И затем я хочу умножить a на (второй столбец матрицы m), вот так

a  *  m[:,1]    =   x1

А затем 3-й и 4-й столбцы

a  *  m[:,2]    =   x2
a  *  m[:,3]    =   x3

И, наконец, я хочу поместить полученные матрицы x0, x1, x2, x3 все в одна матрица.

X = [x0, x1, x2, x3]

Размер X в этом примере равен 4 x 8.

Окончательный результат в этом примере:

X = 

[[[1 5 0 0 0 0 1 5]
  [2 6 0 0 2 6 0 0]
  [0 0 3 7 0 0 3 7]
  [0 0 4 8 4 8 4 8]]

Я хотел бы знать, как это сделать с помощью встроенных функций numpy и использования генераторов вместо использования 2 для циклов, если это возможно.

Это всего лишь пример. На самом деле матрицы имеют большие размеры, и важно, чтобы умножения выполнялись как можно быстрее.

Спасибо

Ответы [ 3 ]

1 голос
/ 06 апреля 2020

Вы можете добиться этого с помощью трансляции и изменения формы

arr_out = (a[:,None] * m[...,None]).reshape(4,8)

Out[176]:
array([[1, 5, 0, 0, 0, 0, 1, 5],
       [2, 6, 0, 0, 2, 6, 0, 0],
       [0, 0, 3, 7, 0, 0, 3, 7],
       [0, 0, 4, 8, 4, 8, 4, 8]])
1 голос
/ 06 апреля 2020

Вы можете транспонировать и расширять измерения m, чтобы получить желаемый результат:

m.T[...,None] * a

array([[[1, 5],
        [2, 6],
        [0, 0],
        [0, 0]],

       [[0, 0],
        [0, 0],
        [3, 7],
        [4, 8]],
        ...

Если вы хотите разместить массивы горизонтально, чтобы получить массив 2D, используйте np.hstack:

np.hstack(m.T[...,None] * a)

array([[1, 5, 0, 0, 0, 0, 1, 5],
       [2, 6, 0, 0, 2, 6, 0, 0],
       [0, 0, 3, 7, 0, 0, 3, 7],
       [0, 0, 4, 8, 4, 8, 4, 8]])

Или изменить форму:

(a[:,None] * m[...,None]).reshape(m.shape[0], -1)
0 голосов
/ 06 апреля 2020

Это ответ, который я искал. Спасибо Yatu и hpaulj.

X = m.T[...,None] * a
for i in range(4):
    reshaped = np.hstack(X[i,:,:])
    reshaped_simpler = np.hstack(X)
print (reshaped_simpler)

Остальную часть ответа я получил по следующей ссылке:

изменить форму numpy 3D-массив в 2D

Я переставил для l oop, потому что получил предупреждение о том, что генераторы будут удалены в будущих версиях Numpy.

...