将数组矩阵与矢量相乘;返回向量数组?

时间:2016-03-09 14:40:10

标签: python arrays numpy matrix

我有一个形状为(n,3)的行向量的numpy数组和另一个形状为矩阵的numpy数组(n,3,3)。我想将n个向量中的每一个与相应的矩阵相乘,并返回结果向量的形状(n,3)数组。

到目前为止,我一直在使用for循环遍历n个向量/矩阵,并逐项进行乘法运算。

我想知道是否有更多的numpy-ish方式。没有for循环的方法甚至可能更快。

//编辑1:

根据要求,这是我的循环代码(使用n = 10):

    arr_in = np.random.randn(10, 3)
    matrices = np.random.randn(10, 3, 3)

    for i in range(arr_in.shape[0]): # 10 iterations
        arr_out[i] = np.asarray(np.dot(arr_in[i], matrices[i]))

2 个答案:

答案 0 :(得分:1)

dot-product基本上沿着两个输入数组的axis=1执行减少。尺寸可以表示为 -

arr_in   :     n   3 
matrices : n   3   3

因此,解决问题的一种方法是推动"推动" arr_in的维度前置一个axis/dimension,从而在其3D阵列版本的axis=2处创建单个维度。然后,沿axis = 1减少元素的总和会给我们所需的输出。让我们展示一下 -

arr_in   : n   [3]   1 
matrices : n   [3]   3

现在,这可以通过两种方式实现。

1)使用np.einsum -

np.einsum('ij,ijk->ik',arr_in,matrices)

2)使用NumPy broadcasting -

(arr_in[...,None]*matrices).sum(1)

运行时测试和验证输出(适用于einsum版本) -

In [329]: def loop_based(arr_in,matrices):
     ...:     arr_out = np.zeros((arr_in.shape[0], 3))
     ...:     for i in range(arr_in.shape[0]):
     ...:         arr_out[i] =  np.dot(arr_in[i], matrices[i])
     ...:     return arr_out
     ...: 
     ...: def einsum_based(arr_in,matrices):
     ...:     return np.einsum('ij,ijk->ik',arr_in,matrices)
     ...: 

In [330]: # Inputs
     ...: N = 16935
     ...: arr_in = np.random.randn(N, 3)
     ...: matrices = np.random.randn(N, 3, 3)
     ...: 

In [331]: np.allclose(einsum_based(arr_in,matrices),loop_based(arr_in,matrices))
Out[331]: True

In [332]: %timeit loop_based(arr_in,matrices)
10 loops, best of 3: 49.1 ms per loop

In [333]: %timeit einsum_based(arr_in,matrices)
1000 loops, best of 3: 714 µs per loop

答案 1 :(得分:0)

您可以使用np.einsum。要为每个矢量矩阵对获取v.dot(M),请使用np.einsum("...i,...ij", arr_in, matrices)。要M.dot(v)使用np.einsum("...ij,...i", matrices, arr_in)

相关问题