python中使用numpy包的向量矩阵相乘np.dot和np.matmul实现

 更新时间:2023年02月15日 09:38:08   作者:ViviranZ  
本文主要介绍了python中使用numpy包的向量矩阵相乘np.dot和np.matmul实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

一直对np的线性运算不太清晰,正好上课讲到了,做一个笔记整个理解一下 

1.向量和矩阵

在numpy中,一重方括号表示的是向量vector,vector没有行列的概念。二重方括号表示矩阵matrix,有行列。

代码显示如下:

import numpy as np
a=np.array([1,2,3])
a.shape
#(3,)
b=np.array([[1,2,3],[3,4,5]])
b.shape
#(2, 3)
c=np.array([[1],[2],[3]])
c.shape
#(3, 1)

即使[1,2,3]、[[1,2,3]]看起来内容一样 使用过程中也会有完全不一样的变化。下面以向量乘法为例解释。

2.向量和向量乘法

1.* 对应对应位置相乘

普通的*:在numpy里表示普通的对应位置相乘,注意相乘的两个向量、矩阵要保证维数相同

a1=np.array([1,2,3])
a2=np.array([1,2,3])
a1*a2
#array([1, 4, 9])
 
b1=np.array([[1,2,3]])
b2=np.array([[1,2,3]])
b1*b2
#array([[1, 4, 9]])
 
b1=np.array([[1,2,3],[3,4,5]])
b2=np.array([[1,2,3],[3,4,5]])
b1*b2
# array([[ 1,  4,  9],
#        [ 9, 16, 25]])

2.广播机制

如果单纯出现维数对不上,python会报error

b1=np.array([[1,2]])
b2=np.array([[1,2,3]])
b1*b2
#operands could not be broadcast together with shapes (1,2) (1,3) 

但是,还有一种情况会出现乘出来一个好大的矩阵,这个情况常出现在无意之中把行、列的数字搞反的情况下。被称为广播机制,需要两个乘子都有一个维数是1,如果是对不上且不为1就会报错

Numpy中的广播机制,你确定正确理解了吗?

在普通的对应位置相乘,会出现 

a1=np.array([1,2,3])
a3=np.array([[1],[2],[3]])
a1*a3#broadcast together
# array([[1, 2, 3],
#        [2, 4, 6],
#        [3, 6, 9]])

倒过来也会出现

a1=np.array([1,2,3])
a3=np.array([[1],[2],[3]])
a3*a1#broadcast together
# array([[1, 2, 3],
#        [2, 4, 6],
#        [3, 6, 9]])

3.向量点乘np.dot

必须要(行向量,列向量)形式的输入

a1=np.array([1,2,3])
a3=np.array([[1],[2],[3]])
np.dot(a3,a1)
#array([14])
#ValueError: shapes (3,1) and (3,) not aligned: 1 (dim 1) != 3 (dim 0)

 都是行向量,不行

b1=np.array([[1,2,3]])
b2=np.array([[1,2,3]])
np.dot(b1,b2) 
#shapes (1,3) and (1,3) not aligned: 3 (dim 1) != 1 (dim 0)

都是列向量,触发广播机制

a1=np.array([[1,2,3]])
a3=np.array([[1],[2],[3]])
np.dot(a3,a1)
# array([[1, 2, 3],
#        [2, 4, 6],
#        [3, 6, 9]])

3.矩阵和向量乘法

1.对应位置相乘

如果单纯采用*的方式进行矩阵和向量乘法,那就是广播机制

矩阵+向量

A1=np.array([[1,2,3],[2,3,4]])
b1=np.array([1,2,3])
A1*b1 #broadcast together
# array([[ 1,  4,  9],
#        [ 2,  6, 12]])

 对应的向量如果是矩阵形式,结果相同

A2=np.array([[1,2,3],[2,3,4]])
b2=np.array([[1,2,3]])
A2*b2 #broadcast together
# array([[ 1,  4,  9],
#        [ 2,  6, 12]])

相似的,如果维数对不上,不会触发广播机制

A3=np.array([[1,2,3],[2,3,4]])
b3=np.array([[1],[2],[3]])
A3*b3 #operands could not be broadcast together with shapes (2,3) (3,1) 

2.矩阵乘法

如果真正想要算矩阵*向量的矩阵乘法,要用np.dot

A4=np.array([[1,2,3],[2,3,4]])
b4=np.array([1,2,3])
np.dot(A4,b4)#dot product
#array([14, 20])

列向量也有类似结果

A4=np.array([[1,2,3],[2,3,4]])
b4=np.array([[1],[2],[3]])
np.dot(A4,b4)#dot product
# array([[14],
#        [20]])

4.矩阵矩阵乘法 

1.直接相乘

同样,也是对应位置相乘

A4=np.array([[1,2,3],[2,3,4]])
B4=np.array([[1,2,3],[4,5,6]])
A4*B4
# array([[ 1,  4,  9],
#        [ 8, 15, 24]])

 有广播机制

A4=np.array([[1,2,3],[2,3,4]])
B4=np.array([[1,2,3]])
A4*B4
# array([[ 1,  4,  9],
#        [ 2,  6, 12]])

2.np.dot

需要第一个的列数和第二个的行数相对应

A4=np.array([[1,2,3],[2,3,4]])
B4=np.array([[1,2,3],[4,5,6]])
np.dot(A4,B4.T)
# array([[14, 32],
#        [20, 47]])
 
A5=np.array([[1,2,3],[2,3,4]])
B5=np.array([[1,2,3],[4,5,6],[7,8,9]])
np.dot(A5,B5)
# array([[30, 36, 42],
#        [42, 51, 60]])

对不上会报错

A4=np.array([[1,2,3],[2,3,4]])
B4=np.array([[1,2,3],[4,5,6]])
np.dot(A4,B4)
# shapes (2,3) and (2,3) not aligned: 3 (dim 1) != 2 (dim 0)

5.np.dot 和np.matmul的区别

Numpy中np.dot与np.matmul的区别

主要参考以上博客。

1.在二维(矩阵中),二者是一致的

2.在三维(张量中),二者有差别。

 以原博客中的例子为例

a = np.array([i for i in range(12)]).reshape([2,2,3])
b = np.array([i for i in range(12)]).reshape([2,3,2])
"""
a
[[[ 0  1  2]
  [ 3  4  5]]
 [[ 6  7  8]
  [ 9 10 11]]]
b
[[[ 0  1]
  [ 2  3]
  [ 4  5]]
 [[ 6  7]
  [ 8  9]
  [10 11]]]
"""

np.dot很清晰,就是a的每一行分别和b的两层乘起来,于是2*2输出了四个“矩阵”(表示成4维的常数):

 
"""
a11= [ 0  1  2]
a12= [ 3  4  5]
a21= [ 6  7  8]
a22= [ 9 10 11]
b
[[[ 0  1]
  [ 2  3]
  [ 4  5]]
 [[ 6  7]
  [ 8  9]
  [10 11]]]
c[:,i,j]=aij*b
"""

如:

[ 10,  13] =[0 1 2]*[[ 0  1]
                                [ 2  3]
                                [ 4  5]]
  [ 28,  31]=[0 1 2]*[[ 6  7]
                                [ 8  9]
                                [ 10  11]]

>>> np.dot(a,b)
array([[[[ 10,  13],
         [ 28,  31]],
 
        [[ 28,  40],
         [100, 112]]],
 
 
       [[[ 46,  67],
         [172, 193]],
 
        [[ 64,  94],
         [244, 274]]]])
>>> np.dot(a,b).shape
(2, 2, 2, 2)

np.matmul的结果:

>>> np.matmul(a,b)
array([[[ 10,  13],
        [ 28,  40]],
 
       [[172, 193],
        [244, 274]]])
>>> np.matmul(a,b).shape
(2, 2, 2)

可以看出,如果把np.dot视为8行、matmul视为4行的话,matmul正好取第1、3、6、8四行,也就是第一层的前两行和第二层的后两行……

直观理解,ok

到此这篇关于python中使用numpy包的向量矩阵相乘np.dot和np.matmul实现的文章就介绍到这了,更多相关numpy向量矩阵相乘np.dot和np.matmul内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • python中*args与**kwarsg及闭包和装饰器的用法

    python中*args与**kwarsg及闭包和装饰器的用法

    这篇文章主要介绍了python中*args与**kwarsg及闭包和装饰器的用法说明,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-07-07
  • 利用Python批量导出mysql数据库表结构的操作实例

    利用Python批量导出mysql数据库表结构的操作实例

    这篇文章主要给大家介绍了关于利用Python批量导出mysql数据库表结构的相关资料,需要的朋友可以参考下
    2022-08-08
  • Python使用scipy.fft进行大学经典的傅立叶变换

    Python使用scipy.fft进行大学经典的傅立叶变换

    傅里叶变换是在高数是一个很重要的知识点,本文将介绍Python使用scipy.fft进行大学经典的傅立叶变换,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2021-06-06
  • Pytorch实现各种2d卷积示例

    Pytorch实现各种2d卷积示例

    今天小编就为大家分享一篇Pytorch实现各种2d卷积示例,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2019-12-12
  • Django封装交互接口代码

    Django封装交互接口代码

    这篇文章主要介绍了Django封装交互接口代码,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-07-07
  • 浅谈如何使用Python控制手机(一)

    浅谈如何使用Python控制手机(一)

    这篇文章主要为大家介绍了如何使用Python控制手机,具有一定的参考价值,感兴趣的小伙伴们可以参考一下,希望能够给你带来帮助
    2021-11-11
  • python黑魔法之编码转换

    python黑魔法之编码转换

    这篇文章主要介绍了python黑魔法之编码转换,分析了python编码转换的方法,感兴趣的小伙伴们可以参考一下
    2016-01-01
  • python单例模式实例分析

    python单例模式实例分析

    这篇文章主要介绍了python单例模式,实例分析了单例模式的原理与使用技巧,具有一定参考借鉴价值,需要的朋友可以参考下
    2015-04-04
  • 浅析Python自带性能强悍的标准库itertools

    浅析Python自带性能强悍的标准库itertools

    itertools是python内置的模块,使用简单且功能强大。这篇文章就主要介绍了通过itertools实现可迭代对象的无限迭代、有限迭代和排列组合。感兴趣的同学可以关注一下
    2021-12-12
  • Python使用sqlalchemy模块连接数据库操作示例

    Python使用sqlalchemy模块连接数据库操作示例

    这篇文章主要介绍了Python使用sqlalchemy模块连接数据库操作,结合实例形式分析了sqlalchemy模块的安装及连接、调用数据库相关操作技巧,需要的朋友可以参考下
    2019-03-03

最新评论