2012-08-07 80 views
22

假设您有n个矩阵A1,...,An。无论如何要以一种整洁的方式增加这些矩阵?就我所知,numpy中的点只接受两个参数。一个明显的方法是定义一个函数来调用它自己并获得结果。有没有更好的方法来完成它?在numpy中乘以几个矩阵

回答

38

这可能是一个相对较新的功能,但我很喜欢:

A.dot(B).dot(C) 

,或者如果你有一个长链,你可以这样做:

reduce(numpy.dot, [A1, A2, ..., An]) 

更新:

还有更多有关减少的信息here.以下是可能有所帮助的示例。

>>> A = [np.random.random((5, 5)) for i in xrange(4)] 
>>> product1 = A[0].dot(A[1]).dot(A[2]).dot(A[3]) 
>>> product2 = reduce(numpy.dot, A) 
>>> numpy.all(product1 == product2) 
True 

更新2016年 由于蟒蛇3.5的,有一个新的matrix_multiply符号,@

R = A @ B @ C 
+0

感谢您的回复。第一个选项正常工作;但第二个没有;或者至少我不能让它工作。你能否详细说明一下,或者举个例子?非常感谢 – NNsr 2012-08-07 05:41:45

+4

我一直遇到这个问题,最后写了一个辅助函数。希望这是NumPy的一部分:'def xdot(* args):return reduce(np.dot,args)' – rd11 2014-07-03 09:57:01

+0

只需在A,B和C的类型为numpy.ndarray时添加此注释。这可能适用于其他类型,但我没有检查。 – OfLettersAndNumbers 2017-12-12 23:37:22

3

如果您先计算所有矩阵,那么您应该使用矩阵链乘法的优化方案。见this Wikipedia article

+2

感谢您的评论;但我不认为它是重要的矩阵。对? – NNsr 2012-08-07 02:35:59

+0

@Nikandish:正确。我错过了原来答案中的那部分内容。 – 2012-08-08 14:57:05

2
A_list = [np.random.randn(100, 100) for i in xrange(10)] 
B = np.eye(A_list[0].shape[0]) 
for A in A_list: 
    B = np.dot(B, A) 

C = reduce(np.dot, A_list) 

assert(B == C) 
16

复活与更新一个老问题:

由于November 13, 2014

现在有一个 np.linalg.multi_dot功能,它正是你想要的。它还具有优化呼叫订单的优点,但在您的情况下这不是必需的。

请注意,这可从numpy版本1.10开始。

0

实现此目的的另一种方法是使用einsum,它为NumPy实现Einstein summation convention

非常简单解释一下这个公约就这一问题:当你写下你的多重矩阵产品作为产品之一之大,你喜欢的东西:

P_im = sum_j sum_k sum_l A1_ij A2_jk A3_kl A4_lm 

其中P的结果是你的产品和A1,A2,A3A4是输入矩阵。请注意,您总结的是加数中出现两次的索引,即j,kl。由于这个属性的总和常常出现在物理学,矢量演算以及其他一些领域,所以它有一个NumPy工具,即einsum

在上面的例子中,你可以用它来计算你的矩阵产品如下:

P = np.einsum("ij,jk,kl,lm", A1, A2, A3, A4) 

这里,第一个参数告诉该指数适用于参数矩阵,然后将所有倍加出现指数函数总结,产生所需的结果。

注意的是,计算效率取决于几个因素(所以你可能是最好关闭只测试它):