Быстрый способ подсчета суммы по внешним произведениям двумерного массива, имеющего форму (2, 5) в numpy - PullRequest
0 голосов
/ 08 октября 2018

У меня есть массивный двумерный массив, имеющий форму (2, 5) (может быть больше измерений (m, n))

A=array([[2.64859009e-02, 2.17771938e-02, 2.38019379e+00, 7.35715883e-01,6.89917290e-01],
      [6.89917290e-01, 5.67262659e-01, 6.20004150e+01, 1.91642758e+01,1.79712923e+01]]

Я хочу сгенерировать две матрицы 5 на 5, который является внешним произведением каждого массива в самом массиве А.

Первая матрица должна быть внешним произведением [2.64859009e-02, 2.17771938e-02, 2.38019379e+00, 7.35715883e-01,6.89917290e-01] с [2.64859009e-02, 2.17771938e-02, 2.38019379e+00, 7.35715883e-01,6.89917290e-01], а вторая матрица должна быть внешним произведением [6.89917290e-01, 5.67262659e-01, 6.20004150e+01, 1.91642758e+01,1.79712923e+01] с [6.89917290e-01, 5.67262659e-01, 6.20004150e+01, 1.91642758e+01,1.79712923e+01].

После этого расчетаЯ хочу суммировать по каждому элементу из двух матриц 5 на 5, который в итоге выдает одну матрицу 5 на 5.

A[0] outer* A[0] + A[1] outer* A[1]

Есть ли быстрый способ сделать это в numpy?

Ответы [ 2 ]

0 голосов
/ 08 октября 2018

Давайте создадим более простой тестовый массив:

In [254]: A = np.arange(10).reshape(2,5)
In [255]: A
Out[255]: 
array([[0, 1, 2, 3, 4],
       [5, 6, 7, 8, 9]])
In [256]: A.shape
Out[256]: (2, 5)

Учитывая способ описания проблемы, np.outer должно быть легко применимо:

In [257]: np.outer(A[0],A[0])+np.outer(A[1],A[1])
Out[257]: 
array([[25, 30, 35, 40, 45],
       [30, 37, 44, 51, 58],
       [35, 44, 53, 62, 71],
       [40, 51, 62, 73, 84],
       [45, 58, 71, 84, 97]])

np.outer работает толькос 1d массивами, а не целыми 2d A.Но мы можем сделать то же самое outer, используя broadcasting.Результатом будет массив (2,5,5), который мы затем можем суммировать по первой оси:

In [260]: (A[:,:,None]*A[:,None,:]).sum(axis=0)
Out[260]: 
array([[25, 30, 35, 40, 45],
       [30, 37, 44, 51, 58],
       [35, 44, 53, 62, 71],
       [40, 51, 62, 73, 84],
       [45, 58, 71, 84, 97]])

np.einsum также является удобным способом описания операций такого типа (если выиспользуются для работы с индексами оси):

In [261]: np.einsum('ij,ik->jk',A,A)
Out[261]: 
array([[25, 30, 35, 40, 45],
       [30, 37, 44, 51, 58],
       [35, 44, 53, 62, 71],
       [40, 51, 62, 73, 84],
       [45, 58, 71, 84, 97]])

Но это einsum, безусловно, выглядит как dot продукт, сумма продуктов.Нам просто нужно транспонировать первый массив:

np.einsum('ji,ik->jk', A.T,A)   

или np.dot:

In [262]: np.dot(A.T,A)
Out[262]: 
array([[25, 30, 35, 40, 45],
       [30, 37, 44, 51, 58],
       [35, 44, 53, 62, 71],
       [40, 51, 62, 73, 84],
       [45, 58, 71, 84, 97]])
0 голосов
/ 08 октября 2018

Вы можете использовать np.outer метод из здесь .

A=np.array([[2.64859009e-02, 2.17771938e-02, 2.38019379e+00, 7.35715883e-01,6.89917290e-01],[6.89917290e-01, 5.67262659e-01, 6.20004150e+01, 1.91642758e+01,1.79712923e+01]]) b = np.outer(A[0],A[0]) c = np.outer(A[1],A[1])

Для выполнения последнего шага достаточно простой суммы b+c.

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