如何在python中为每一对分离矩阵向量内积?

时间:2016-12-16 18:24:01

标签: python numpy matrix vector

让我们说,我有一堆矩阵As和向量bs。

As = array([[[1, 7], [3, 8]],
            [[2, 1], [5, 9]],
            [[7, 2], [8, 3]]])
bs = array([[8, 0], [8, 8], [7, 3]])

当我做np.inner(As,bs)时,我得到:

array([[[  8,  64,  28], [ 24,  88,  45]],
       [[ 16,  24,  17], [ 40, 112,  62]],
       [[ 56,  72,  55], [ 64,  88,  65]]])

但我不需要所有的内在产品。我想要的是,用每个向量计算一次矩阵。 我可以这样做:

np.array(map(lambda (a, b): np.inner(a, b), zip(As, bs)))

然后我得到了预期的矩阵:

array([[  8,  24], [ 24, 112], [ 55,  65]])

现在我不想使用zip,map等因为我需要这个操作> 10 ** 6次(用于图像处理,完全用于GMM)。 有没有办法使用numpy,scipy等可以为我做这个? (快速而有效)

1 个答案:

答案 0 :(得分:3)

您可以使用np.einsum -

np.einsum('ijk,ik->ij',As, bs)

<强>解释

使用np.array(map(lambda (a, b): np.inner(a, b), zip(As, bs))),我们选择As关闭的第一个元素为a,关闭bsb并执行内部产品。因此,我们正在做:

In [19]: np.inner(As[0],bs[0])
Out[19]: array([ 8, 24])

In [20]: np.inner(As[1],bs[1])
Out[20]: array([ 24, 112])

In [21]: np.inner(As[2],bs[2])
Out[21]: array([55, 65])

将其视为一个循环,我们迭代3次,对应于As的第一轴的长度,这与bs相同。因此,查看lambda表达式,在每次迭代时,我们都有a = As[0] & b = bs[0]a = As[1] & b = bs[1]等等。

Asbs3D2D,让我们将它们表示为想象我们思想中的内在产品的迭代器。因此,在迭代时,我们将a : j,kb : m。使用ab之间的内部产品,我们将丢失a的第二个轴和b的第一个轴。因此,我们需要将km对齐。因此,我们可以假设b具有与k相同的迭代器。从a返回到Asb再到bs,实质上我们会从As丢失第三个轴,从bs丢失第二个轴与内在产品/总和减少。沿着Asbs的第一个轴进行迭代表示我们需要在这些总和减少下保持这些对齐。

让我们总结一下。

我们有输入数组的迭代器,如此 -

As :  i x j x k 
bs :  i x k

预期操作涉及的步骤:

  • 保持As的第一个轴与bs的第一个轴对齐。
  • 丢失As的第三个轴,减去总和 - bs的第二个。

因此,我们将留下输出的迭代器i,j

np.einsum是一种非常有效的实现,当我们需要保持输入数组的一个或多个轴彼此对齐时,它非常方便。

有关einsum的更多信息,我建议您按照之前提供的文档链接进行操作,this Q&A也可以提供帮助!