numpy einsum for y =(x*A)@A.T

vnzz0bqm  于 12个月前  发布在  其他
关注(0)|答案(1)|浏览(99)

np.einsum看起来不错,但是(对我来说)用在更难的表达式上很复杂。在这里等价的表达式是什么?

import numpy as np
x = np.array([1.,2.,3.])
A = np.array([[3.,4.,5],
               [2.,2.,2.]])
y = (x*A)@A.T

# y2 = np.einsum('what to write here', x, A)

我可以重新创建每个基本步骤,如下所示,但我很难在一个np.einsum()中完成所有事情。

xA = np.einsum('i, ji->ji', x,A) # x*A
At = np.einsum('ij->ji', A) #A.T
y2 = np.einsum('ij, jk', xA, At) # xA @ At
assert (y==y2).all() #evaluates to true

请注意,在上面的例子中,A是2x3矩阵,但在我的实际代码中,它可以是1000x3矩阵或更大。

q9rjltbz

q9rjltbz1#

关于Einsum
您可以将这些操作合并组合到单个np.einsum函数中。

import numpy as np
x = np.array([1.,2.,3.])
A = np.array([[3.,4.,5],
              [2.,2.,2.]])
y = (x*A)@A.T

# y2 = np.einsum('what to write here', x, A)
y2 = np.einsum('i,ij,jk->ik', x, A, A.T)

assert (y==y2).all()  # evaluates to true

说明:
在“i,ij,jk->ik”部分,我们说:

  • 'i':使用x数组。
  • “ij”:使用A矩阵。
  • 'jk':使用转置A矩阵(A.T)。
  • '-> ik':给予我们输入的外部尺寸的结果。

所以基本上,我们做的操作和你的长代码一样,但是都是一步完成的。它将x乘以A,然后将结果乘以A.T,得到与y匹配的最终结果。

备选

虽然如果你不喜欢使用einsum,你可以使用标准的numpy操作,如广播和矩阵乘法(@)来实现相同的结果。

import numpy as np

x = np.array([1., 2., 3.])
A = np.array([[3., 4., 5],
              [2., 2., 2.]])
y = (x * A) @ A.T

# Alternative to einsum
xA = x[:, None] * A  # Equivalent to x*A using broadcasting
y2 = xA @ A.T  # Matrix multiplication with A.T

assert (y == y2).all()  # This checks that y and y2 are the same

说明:

  • x[:, None]:我们为x添加一个新轴,使其成为列向量。当我们将其乘以A时,这有助于广播。
  • xA @ A.T:我们在结果(xA)和AA.T)的转置之间执行矩阵乘法,以获得最终结果。

这将为您提供与einsum方法相同的给予输出,但使用更传统的numpy操作。

相关问题