Skip to main content
 首页 » 编程设计

python之矩阵数组的逐元素有效乘法

2025年05月04日17tuyile006

假设 array_1 和 array_2 是两个大小相同的矩阵数组。是否有任何向量化的方式将这两个数组的元素相乘(它们的元素乘法定义明确)?

伪代码:

def mat_multiply(array_1,array_2): 
    size=np.shape(array_1)[0] 
 
    result=np.array([]) 
    for i in range(size): 
        result=np.append(result,np.dot(array_1[i],array_2[i]),axis=0) 
    return np.reshape(result,(size,2)) 

示例输入:

a=[[[1,2],[3,4]],[[1,2],[3,4]]] 
b=[[1,3],[4,5]] 

输出:

[[  7.  15.] 
 [ 14.  32.]] 

请您参考如下方法:

与您的第一句话相反,a 和 b 的大小不同。但让我们专注于您的示例。

所以你想要这个 - 2 个点积,每行一个 a 和 b

np.array([np.dot(x,y) for x,y in zip(a,b)]) 

或避免附加

X = np.zeros((2,2)) 
for i in range(2): 
    X[i,...] = np.dot(a[i],b[i]) 

点积可以用einsum(矩阵索引表示法)表示为

[np.einsum('ij,j->i',x,y) for x,y in zip(a,b)] 

所以下一步是索引第一个维度:

np.einsum('kij,kj->ki',a,b) 

我对 einsum 非常熟悉,但仍然需要反复试验才能弄清楚您想要什么。现在问题很清楚了,我可以用其他几种方式计算它

A, B = np.array(a), np.array(b)     
np.multiply(A,B[:,np.newaxis,:]).sum(axis=2) 
(A*B[:,None,:]).sum(2) 
np.dot(A,B.T)[0,...] 
np.tensordot(b,a,(-1,-1))[:,0,:] 

我发现使用不同大小的数组很有帮助。例如,如果 A 是 (2,3,4) 和 B (2,4),它将更明显点和必须在最后一个维度上。


另一个 numpy 迭代工具是 np.nditer。 einsum 使用它(在 C 中)。 http://docs.scipy.org/doc/numpy/reference/arrays.nditer.html

it = np.nditer([A, B, None],flags=['external_loop'], 
    op_axes=[[0,1,2], [0,-1,1], None]) 
for x,y,w in it: 
    # x, y are shape (2,) 
    w[...] = np.dot(x,y) 
it.operands[2][...,0] 

避免 [...,0] 步骤需要更精细的设置。

C = np.zeros((2,2)) 
it = np.nditer([A, B, C],flags=['external_loop','reduce_ok'], 
    op_axes=[[0,1,2], [0,-1,1], [0,1,-1]], 
    op_flags=[['readonly'],['readonly'],['readwrite']]) 
for x,y,w in it: 
    w[...] = np.dot(x,y) 
    # w[...] += x*y  
print C 
# array([[  7.,  15.],[ 14.,  32.]])