Python 关于矩阵乘法的几个问题?
我要执行以下操作: 给定一个n乘m的矩阵m和一个k乘1的向量V,我们首先取V和m的行的乘积 这里,v与M的乘积给出了一个k×M矩阵。因此,我们期望在乘法后得到nk×m矩阵。接下来,我们需要取n个矩阵的和,然后除以n。就拿平均值来说吧 具体来说,Python 关于矩阵乘法的几个问题?,python,numpy,Python,Numpy,我要执行以下操作: 给定一个n乘m的矩阵m和一个k乘1的向量V,我们首先取V和m的行的乘积 这里,v与M的乘积给出了一个k×M矩阵。因此,我们期望在乘法后得到nk×m矩阵。接下来,我们需要取n个矩阵的和,然后除以n。就拿平均值来说吧 具体来说,设v=[1,2,3],M=[1,2][3,4][5,6] 返回平均值(v,M)给出([1,2],[2,4],[3,6]+[3,4],[6,8],[9,12]+[5,6],[10,12],[15,18]])/3 所以 我会做类似的事情 temp= np.ze
设v=[1,2,3],M=[1,2][3,4][5,6]
返回平均值(v,M)
给出([1,2],[2,4],[3,6]+[3,4],[6,8],[9,12]+[5,6],[10,12],[15,18]])/3
所以
我会做类似的事情
temp= np.zeros(len(v),np.shape(M)[1])
for i in range(np.shape(M)[0]):
temp=temp+v[:,None]*M[i,:][None,:]
return temp/np.shape(M)[0]
我想知道numpy中是否有这样的构建方法?我认为使用乘法ufunc的外部方法可以满足您的需要
M=np.array([[1,2],[3,4],[5,6]])
v=np.array([1,2,3])
res = np.multiply.outer(M, v)
res
# array([[[ 1, 2, 3],
# [ 2, 4, 6]],
# [[ 3, 6, 9],
# [ 4, 8, 12]],
# [[ 5, 10, 15],
# [ 6, 12, 18]]])
res/M.shape[0]
# array([[[0.33333333, 0.66666667, 1. ],
# [0.66666667, 1.33333333, 2. ]],
# [[1. , 2. , 3. ],
# [1.33333333, 2.66666667, 4. ]],
# [[1.66666667, 3.33333333, 5. ],
# [2. , 4. , 6. ]]])
res.shape # (3, 2, 3)
你的计算:
In [206]: temp= np.zeros([len(v),np.shape(M)[1]])
...: for i in range(np.shape(M)[0]):
...: temp=temp+v[:,None]*M[i,:][None,:]
...: temp1 = temp/np.shape(M)[0]
In [207]: temp
Out[207]:
array([[ 9., 12.],
[18., 24.],
[27., 36.]])
In [208]: temp1
Out[208]:
array([[ 3., 4.],
[ 6., 8.],
[ 9., 12.]])
一次对所有i
执行广播乘法:
In [211]: v[:,None]*M[:,None,:] # or v[None,:,None]
Out[211]:
array([[[ 1, 2],
[ 2, 4],
[ 3, 6]],
[[ 3, 4],
[ 6, 8],
[ 9, 12]],
[[ 5, 6],
[10, 12],
[15, 18]]])
In [212]: _.sum(axis=0) # and the sum
Out[212]:
array([[ 9, 12],
[18, 24],
[27, 36]])
使用einsum:
In [214]: np.einsum('j,ik->ijk', v, M)
Out[214]: # same a 211
...
在i
上求和:
In [215]: np.einsum('j,ik->jk', v, M)
Out[215]:
array([[ 9, 12],
[18, 24],
[27, 36]])
这表明我们可以首先在M
的第一维度上求和:
In [217]: v[:,None]*M.sum(axis=0)[None,:]
Out[217]:
array([[ 9, 12],
[18, 24],
[27, 36]])
甚至在这个维度上取平均值:
In [218]: v[:,None]*M.mean(axis=0)[None,:]
Out[218]:
array([[ 3., 4.],
[ 6., 8.],
[ 9., 12.]])
In [227]: v[:,None]@M.mean(axis=0, keepdims=True)
Out[227]:
array([[ 3., 4.],
[ 6., 8.],
[ 9., 12.]])
要使用点矩阵乘法,我们必须构造一个(3,3)v
数组来处理(3,2)M
:
In [222]: np.column_stack([v,v,v])@M
Out[222]:
array([[ 9, 12],
[18, 24],
[27, 36]])
np.broadcast_to(v[:,None],(3,3))@M
的内存效率更高
或者使用@
作为外部
,虚拟尺寸为1维:
In [218]: v[:,None]*M.mean(axis=0)[None,:]
Out[218]:
array([[ 3., 4.],
[ 6., 8.],
[ 9., 12.]])
In [227]: v[:,None]@M.mean(axis=0, keepdims=True)
Out[227]:
array([[ 3., 4.],
[ 6., 8.],
[ 9., 12.]])