Python 给出一个矩阵列表,求和,但忽略一些矩阵';s行

Python 给出一个矩阵列表,求和,但忽略一些矩阵';s行,python,numpy,matrix,Python,Numpy,Matrix,举个例子,让我们 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

举个例子,让我们

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
的索引矩阵
I
,它为结果
R
的每一行指定
l
中的
k
矩阵中的哪一个应用于计算该行
R
。上面,
I
的第一行是
[1,0,1]
,因此
A
C
用于计算
R
的第一行

我可以使用哪个
numpy
函数进行此操作?

假设:

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 fu不够强大。

我同意@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.对角线(l.T.dot(I.T).T)
)是
[[a1+c1,b3+c3],[a2+c2,b4+c4]


最后,它的转置是:
[[a1+c1,a2+c2],[b3+c3,b4+c4]
假设
l
作为
(n,m)
形数组的输入列表,您可以使用非常高效的,就像这样-

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]])

我对numpy还不太熟悉,无法给出完整的解决方案,但似乎您应该能够重塑数据,使其成为系数矩阵和术语矩阵之间的简单乘法运算。哇,我不知道
einsum
。你能解释一下吗,吉克→ ik?@fabian789基本上,我们是将输入数组与
轴=0
I
轴=1
l
轴=1
I
轴=0
l
对齐。然后,求和减少乘法结果的第一个轴。所有这些都是通过einsum调用在一个有效的步骤中完成的。有关更多信息,请参阅此链接-酷!我接受这一点,因为它似乎是最普遍的。谢谢