【问题标题】:Outer product calculation by numpy einsum通过 numpy einsum 计算外积
【发布时间】:2020-08-21 08:32:06
【问题描述】:

我正在尝试深入研究einsum 符号。这个question and answers对我帮助很大。

但现在我在计算外积时无法掌握einsum的机制:

x = np.array([1, 2, 3])
y = np.array([4, 5, 6])
np.einsum('i,j->ij', x, y)

array([[ 4.,  5.,  6.],
        [ 8., 10., 12.],
        [12., 15., 18.]])

answer 给出了以下规则:

通过在两个输入数组中重复标签 i,我们告诉 einsum 这两个轴应该相乘。

如果我们没有在 np.einsum('i,j->ij', x, y) 中提供任何重复的轴标签,我无法理解这种乘法是如何发生的?

您能否给出np.einsum 在此示例中采取的步骤?

或者更广泛的问题,einsum 在没有给出匹配的轴标签时如何工作?

【问题讨论】:

  • 不在输出字符串中的轴标签,只是沿该轴求和。

标签: python numpy linear-algebra numpy-einsum


【解决方案1】:

np.einsum('i,j->ij', x, y) 的输出中,元素[i,j] 只是x 中的元素iy 中的元素j 的乘积。换句话说,np.einsum('i,j->ij', x, y)[i,j] = x[i]*y[j]

比较它与np.einsum('i,i->i', x, y) 是元素i 的输出是x[i]*y[i]

np.einsum('i,i->i', x, y)

[ 4 10 18]

如果输入中的标签在输出中丢失,则意味着输出已计算出沿丢失标签轴的总和。这是一个简单的例子:

np.einsum('i,j->i', x, y)

[15 30 45]

这里输入中的标签j在输出中缺失,相当于沿axis=1求和(对应标签j):

np.sum(np.einsum('i,j->ij', x, y), axis=1)

[15 30 45]

【讨论】:

    【解决方案2】:

    一般来说,你可以通过准确地知道输入和输出的维度或形状来理解 einsum 符号是预期和计算的。

    为了方便解释,假设 x.shape = [3] , y.shape = [4]

    x = np.array([1, 2, 3])
    y = np.array([4, 5, 6, 7])
    np.einsum('i,j->ij', x, y)
    array([[ 4,  5,  6,  7],
           [ 8, 10, 12, 14],
           [12, 15, 18, 21]])
    

    维度

    对于叉积np.einsum('i,j->ij', x, y),第一个输入是单个字符i。您可以认为字符数是该输入的维度数。所以这里第一个输入x 只有一维。 j 同样,第二个输入也只是一个字符j,所以它只有一维。最后输出ij有2个字符,所以它有2个维度,那个维度必须是[3,4],因为第一个输入中的元素数是i,它有3个元素,第二个元素的数量输入是 j,它有 4 个元素。

    结果数组中的每个元素

    然后,您将关注结果符号ij。现在我们知道它是一个二维数组,或者是一个 3 x 4 矩阵,ij 正在讨论 ONE 元素是如何在ij 列的位置计算的。元素必须从输入的乘积中计算出来。这意味着位置 [i,j] 上的特定元素是其位置 i 的输入 a 和其位置 j 的输入 b 的乘积

    因此,位置 [0,0] 上的元素是通过取第一个输入位置 0(即您的 x[0] = 1)和第二个输入位置 [0] 计算得出的是 y[0] = 4,即 ONE 元素 [0,0] = 1 * 4 = 4 的结果。

    同样,结果位置 [2,3] 上的元素采用 x[2] 和 y[3] = 3 * 7 = 21

    简而言之,认为i,j->ijiji 乘以j 的2 维结果的一个元素(因为2 个字符)。您从输入i 和输入j 获取的实际元素是根据ij 的位置索引

    可以在一行中找到外积的转置

    也就是说,外积的转置就是i,j->ji。在这里,我们的结果中有两个字符,所以它是一个二维数组。第一个维度的元素个数必须是j,因为它在前。它是第二个输入,有 4 个元素。第 2 维的逻辑相同,因此我们知道结果数组是 (4,3) 的形状。

    那么,结果二维数组[3,2]位置的ONE元素为ji,即输入j乘以输入i,所以它是j的元素3 = y[3] = 7 ,i 的元素 2 = x[2] = 3. 结果是 7 * 3 = 21

    因此,结果是

    np.einsum('i,j->ji', x, y)
    array([[ 4,  8, 12],
           [ 5, 10, 15],
           [ 6, 12, 18],
           [ 7, 14, 21]])
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-06-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-05-17
      • 2015-11-16
      • 2017-08-03
      相关资源
      最近更新 更多