Предположим, у меня есть матрица типа numpy:

[[   1    2    3]
 [  10  100 1000]]

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

[1*1 + 10*10    2*2 + 100*100    3*3 + 1000*1000] == [101, 10004, 1000009]

Я хотел бы знать, возможно ли это, используя einsum (и чтобы лучше ее понять).

Пока что ближайший результат, который я мог бы получить:

import numpy as np

arr = np.array([[1, 2, 3], [10, 100, 1000]])

res = np.einsum('ij,ik->jk', arr, arr)

# [[    101    1002   10003]
#  [   1002   10004  100006]
#  [  10003  100006 1000009]]

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

3
Delgan 2 Янв 2018 в 22:43

2 ответа

Лучший ответ

Используйте np.einsum, вот так -

np.einsum('ij,ij->j',arr,arr)

Пробный прогон -

In [243]: np.einsum('ij,ij->j',arr,arr)
Out[243]: array([    101,   10004, 1000009])

Или с np.sum -

In [244]: (arr**2).sum(0)
Out[244]: array([    101,   10004, 1000009])

Или с помощью модуля numexpr -

In [248]: import numexpr as ne

In [249]: ne.evaluate('sum(arr**2,0)')
Out[249]: array([    101,   10004, 1000009])
4
Divakar 2 Янв 2018 в 19:47

То, что вы здесь ожидаете, можно понять интуитивно, выполнив один промежуточный шаг из ответа на einsum от Divakar.

In [19]: arr
Out[19]: 
array([[   1,    2,    3],
       [  10,  100, 1000]])

# simply take element-wise product with the array itself
In [20]: np.einsum('ij, ij -> ij', arr, arr)
Out[20]: 
array([[      1,       4,       9],
       [    100,   10000, 1000000]])

Но это не дает ожидаемого результата. Итак, если вы наблюдаете вышеуказанный результат, нам просто нужно суммировать по первому измерению (то есть по оси 0). Таким образом, мы опускаем индекс i после -> в результате einsum, что означает, что мы просим его суммировать по этой оси, и это дает ожидаемый результат:

In [21]: np.einsum('ij, ij -> j', arr, arr)
Out[21]: array([    101,   10004, 1000009])

P.S. Кроме того, для общего понимания {{X0 }}, см. подробное обсуждение здесь: понимание-numpy-einsum

1
kmario23 4 Янв 2018 в 19:09