2014-04-09 91 views
2

我有一个3xN阵列,概念上的N 3-矢量阵列,我要建构 阵列从矩阵给定3x3矩阵与 阵列的每一列乘以结果。有没有一种以矢量化的方式做到这一点的好方法?numpy的:广播矩阵相乘翻过阵列

目前,我的问题是3xN,但我将来可能需要考虑3xNxM(或更多)。

糊涂的做法

U=numpy.rand([3,24]) 

R=numpy.eye(3) # placeholder 

for i in xrange(U.shape[1]): 
    U[:,i]=numpy.dot(R, U[:,i]) 
+0

在这里看到我的答案:http://stackoverflow.com/a/22081723/553404 – YXD

+0

@MrE的答案是相当不错的,对于我的形状(3xN),我避免了你在那里提到的转置。 – Dave

回答

4

使用np.einsum函数,即使对于多di大小问题:

U = np.random.rand(3,24,5) 
R = np.eye(3,3) 
result = np.einsum("ijk,il", U,R) 

该符号有点棘手:您首先给出的字符串指出了数组维度的单元;所以对于U而言,ijk是每个维度的运行余量。它遵循爱因斯坦求和惯例,所以在字符串中具有相同字母的元素将被求和。详情请参阅ScipyDocs。我敢肯定在你的情况下,点更快,因为开销更少,它可能会使用一些例程,但正如你所说,你想扩展到更多维度,这可能是一条路。

+2

在实际的基准测试中,Einsum经常拉开序幕。特别是在这些涉及小尺寸收缩的情况下。我想通过gufunc机制来调用BLAS;也就是说,每个微小的子矩阵都有一个单独的BLAS调用。在这样的情况下,BLAS会因O(N)的开销而受到影响,这会很快压倒Einsum的O(1)开销。 –

3

在这种情况下,你可以简单地调用np.dot(R, U),它会工作:

import numpy as np 

np.random.seed(0) 

U = np.random.rand(3,24) 
R = np.random.rand(3,3) 

result = np.empty_like(U) 

for i in range(U.shape[1]): 
    result[:,i] = np.dot(R, U[:,i]) 

print result 

print np.allclose(result, np.dot(R, U)) 

对于(3xNxM)情况下,你可以重塑到(3次(NM)),dot和重塑结果回来,类似于我的回答here

+0

我认为使用np.dot时,可以实际上是要走的路,因为它经常使用真正快速的库,如Blas或Lapack进行了高度优化。 – Magellan88