【问题标题】:Given a List of Matrices, Sum Them but Ignore Some Matrix's Rows给定一个矩阵列表,对它们求和但忽略一些矩阵的行
【发布时间】:2016-08-01 04:53:56
【问题描述】:

举个例子,让

A = np.array([[a1, a2],
              [a3, a4]])
B = np.array([[b1, b2],
              [b3, b4]])
C = np.array([[c1, c2],
              [c3, c4]]),

l = [A, B, C],然后让

I = np.array([[1, 0, 1],
              [0, 1, 1]]).

我要计算矩阵R

R = np.array([[a1 + c1, a2 + c2],
              [b3 + c3, b4 + c4]])

即一般来说,我有一个存储在l 中的k nxm 矩阵列表和一个尺寸为nxk 的索引矩阵nxk 指定结果R每一行在计算R 的那一行时,应该使用l 中的哪个k 矩阵。以上,I 的第一行是[1, 0, 1],因此AC 用于计算R 的第一行。

我可以为此使用哪个numpy 函数?

【问题讨论】:

  • 我对 numpy 不够熟悉,无法提供完整的解决方案,但您似乎应该能够重塑您的数据,以便这成为系数矩阵和项矩阵之间的简单乘法运算。

标签: python numpy matrix


【解决方案1】:

假设l作为(n,m)形数组的输入列表,你可以使用非常高效的np.einsum,像这样-

np.einsum('ij,jik->ik',I,l)

示例运行 -

In [75]: # Inputs
    ...: a1,a2,a3,a4 = 4,6,8,2
    ...: b1,b2,b3,b4 = 5,11,4,3
    ...: c1,c2,c3,c4 = 6,99,2,5
    ...: 
    ...: A = np.array([[a1, a2],
    ...:               [a3, a4]])
    ...: B = np.array([[b1, b2],
    ...:               [b3, b4]])
    ...: C = np.array([[c1, c2],
    ...:               [c3, c4]])
    ...: l = [A,B,C]
    ...: 
    ...: I = np.array([[1, 0, 1],
    ...:               [0, 1, 1]])
    ...: # Expected output
    ...: R = np.array([[a1 + c1, a2 + c2],
    ...:               [b3 + c3, b4 + c4]])
    ...: 

In [76]: R
Out[76]: 
array([[ 10, 105],
       [  6,   8]])

In [77]: np.einsum('ij,jik->ik',I,l)
Out[77]: 
array([[ 10, 105],
       [  6,   8]])

【讨论】:

  • 哇,我不知道einsum。你愿意解释一下ij, jik → ik吗?
  • @fabian789 基本上我们将输入数组与来自Iaxis=0 与来自laxis=1 对齐和来自Iaxis=1 与来自@ 的axis=0 对齐987654337@。然后,将乘法结果的第一轴相减。所有这些都是通过 einsum 调用在一个有效的步骤中完成的。欲了解更多信息,请参阅此链接 - stackoverflow.com/questions/26089893/…
  • 酷!我接受这个,因为它似乎是最普遍的。谢谢
【解决方案2】:

我同意@Avish 的观点,这非常像矩阵乘法,但最后你只需要对角线条目:

np.diagonal(l.T.dot(I.T).T).T

它是如何工作的:

l.T 会给[[a1, b1, c1], [a3, b3, c3], [a2, b2, c2], [a4, b4, c4]]

l.T.dot(I.T) 会给[[[a1+c1, b1+c1], [a3+c3, b3+c3]], [[a2+c2, b2+c2], [a4+c4, b4+c4]]]

l.T.dot(I.T).T[[[a1+c1, a2+c2], [a3+c3, a4+c4]], [[b1+c1, b2+c2], [b3+c3, b4+c4]]]

对角线条目(np.diagonal(l.T.dot(I.T).T))是[[a1+c1, b3+c3], [a2+c2, b4+c4]]

最后,它的转置为:[[a1+c1, a2+c2], [b3+c3, b4+c4]]

【讨论】:

    【解决方案3】:

    假设:

    terms = np.array([A, B, C])  # A,B,C are 2x2 matrices
    coeffs = np.array([[1,0,1], [0,1,1]])
    

    你可以这样做:

    # transpose terms to 2x2 matrix of [A,B,C] element vectors,
    # with shape (2,2,3):
    transposed_terms = np.transpose(terms, (1,2,0)) 
    # tile coefficients to align:
    tiled_coeffs = np.tile(coeffs, 2).reshape(2,2,3)
    # element-wise multiplication and sum over last dimension
    return np.sum(transposed_terms, tiled_coeffs, 2)
    

    使用numpy.tensordot 之类的方法可能有更简单的方法,但我的 numpy-fu 不够强大。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-03-04
      • 2018-08-01
      • 2018-09-07
      • 1970-01-01
      • 1970-01-01
      • 2011-02-10
      相关资源
      最近更新 更多