任意形状的NumPy阵列的点积

时间:2016-06-20 19:36:08

标签: python numpy matrix-multiplication

鉴于任意形状的两个$isEvenNumber = function($number) { return $number % 2 == 0; } $numbers = toms(33); $filtered_numbers = array_filter($numbers, $isEvenNumber); var_dump($filtered_numbers); 个对象numpy.ndarrayA,我想计算一个B numpy.ndarray的属性所有C C[i] == np.dot(A[i], B[i])。我怎么能这样做?

示例1:iA.shape==(2,3,4),那么我们应该B.shape==(2,4,5)

示例2:C.shape==(2,3,5)A.shape==(2,3,4),那么我们应该B.shape==(2,4)

2 个答案:

答案 0 :(得分:4)

这是一个使用某些reshapingnp.einsum覆盖各种情况/任意形状的通用解决方案。 einsum在这里有所帮助,因为我们需要沿第一轴对齐并沿输入数组的最后一轴减少。实现看起来像这样 -

def dotprod_axis0(A,B):
    N,nA,nB = A.shape[0], A.shape[-1], B.shape[1]
    Ar = A.reshape(N,-1,nA)
    Br = B.reshape(N,nB,-1)
    return np.squeeze(np.einsum('ijk,ikl->ijl',Ar,Br))

<强>予。答:2D,B:2D

In [119]: # Inputs
     ...: A = np.random.randint(0,9,(3,4))
     ...: B = np.random.randint(0,9,(3,4))
     ...: 

In [120]: for i in range(A.shape[0]):
     ...:     print np.dot(A[i], B[i])
     ...:     
33
86
48

In [121]: dotprod_axis0(A,B)
Out[121]: array([33, 86, 48])

<强> II。答:3D,B:3D

In [122]: # Inputs
     ...: A = np.random.randint(0,9,(2,3,4))
     ...: B = np.random.randint(0,9,(2,4,5))
     ...: 

In [123]: for i in range(A.shape[0]):
     ...:     print np.dot(A[i], B[i])
     ...:     
[[ 74  70  53 118  43]
 [ 47  43  29  95  30]
 [ 41  37  26  23  15]]
[[ 50  86  33  35  82]
 [ 78 126  40 124 140]
 [ 67  88  35  47  83]]

In [124]: dotprod_axis0(A,B)
Out[124]: 
array([[[ 74,  70,  53, 118,  43],
        [ 47,  43,  29,  95,  30],
        [ 41,  37,  26,  23,  15]],

       [[ 50,  86,  33,  35,  82],
        [ 78, 126,  40, 124, 140],
        [ 67,  88,  35,  47,  83]]])

<强> III。答:3D,B:2D

In [125]: # Inputs
     ...: A = np.random.randint(0,9,(2,3,4))
     ...: B = np.random.randint(0,9,(2,4))
     ...: 

In [126]: for i in range(A.shape[0]):
     ...:     print np.dot(A[i], B[i])
     ...:     
[ 87 105  53]
[152 135 120]

In [127]: dotprod_axis0(A,B)
Out[127]: 
array([[ 87, 105,  53],
       [152, 135, 120]])

<强> IV。答:2D,B:3D

In [128]: # Inputs
     ...: A = np.random.randint(0,9,(2,4))
     ...: B = np.random.randint(0,9,(2,4,5))
     ...: 

In [129]: for i in range(A.shape[0]):
     ...:     print np.dot(A[i], B[i])
     ...:     
[76 93 31 75 16]
[ 33  98  49 117 111]

In [130]: dotprod_axis0(A,B)
Out[130]: 
array([[ 76,  93,  31,  75,  16],
       [ 33,  98,  49, 117, 111]])

答案 1 :(得分:0)

假设你想要dot的普通矩阵乘法(不是说,矩阵向量或奇怪的废话dot对更高维度),那么你可以使用最新的NumPy版本(1.10+)

C = numpy.matmul(A, B)

和足够新的Python版本(3.5+)允许你将其写为

C = A @ B

假设你的NumPy也是最近的。