【Python】Numpy之矩阵的相关计算及矩阵的选取与切割

系统 2379 0

Numpy有很多矩阵运算的方法,小白总结了一些常用和认为在算法中用到的方法~

基础操作:

首先创建两个矩阵

            
              A = np.array([[1,2],[1,2]])
B = np.array([[2,4],[5,5]])
            
          

1.矩阵对应位置的元素相加

            
              #矩阵同位置元素相加
np.add(A,B)#方法1
A+B     #方法2
            
          

结果都为:

            
              array([[3, 6],
       [6, 7]])
            
          

2.矩阵对应位置的元素相乘

            
              #矩阵对应位置的每个元素相乘
A*B
            
          

结果为:

            
              array([[ 2,  8],
       [ 5, 10]])
            
          

与之对应的就有矩阵相乘的运算

            
              #矩阵相乘
A.dot(B)   #方法1
np.dot(A,B)#方法2
            
          

结果为:

            
              array([[12, 14],
       [12, 14]])
            
          

进阶操作:

用之前博文中介绍过的arange函数创建一个矩阵

这里用arange中的reshape函数创建了一个6*4的矩阵,如果不指定,默认就是一行的矩阵

            
              A = np.arange(24).reshape(6,4)
            
          

结果为:

            
              array([[ 0,  1,  2,  3],
       [ 4,  5,  6,  7],
       [ 8,  9, 10, 11],
       [12, 13, 14, 15],
       [16, 17, 18, 19],
       [20, 21, 22, 23]])
            
          

创建好矩阵之后来一写进阶的计算:

1)sum函数

    axis就是确定沿矩阵的行或者列进行加和

   axis=0:沿着每一列进行操作(所以返回4个值)
   axis=1:沿着每一行进行操作(6个行返回六个值)

            
              A.sum(axis=0)
A.sum(axis=1)
            
          

axis=0的结果:

            
              array([60, 66, 72, 78])
            
          

axis=1的结果:

            
              array([ 6, 22, 38, 54, 70, 86])
            
          

2)cumsum函数

   axis就是确定沿矩阵的行或者列进行加和

   axis=0:沿着每一列对这个位置及之前位置的元素累加
   axis=1:沿着每一行对这个位置及之前位置的元素累加

            
              A.cumsum(axis=1)
A.cumsum(axis=0)
            
          

 

axis=1的结果:

            
              array([[ 0,  1,  3,  6],
       [ 4,  9, 15, 22],
       [ 8, 17, 27, 38],
       [12, 25, 39, 54],
       [16, 33, 51, 70],
       [20, 41, 63, 86]], dtype=int32)
            
          

axis=0的结果:

            
              array([[ 0,  1,  2,  3],
       [ 4,  6,  8, 10],
       [12, 15, 18, 21],
       [24, 28, 32, 36],
       [40, 45, 50, 55],
       [60, 66, 72, 78]], dtype=int32)
            
          

3.min函数

   axis就是确定沿矩阵的行或者列取最小值

   axis=0:沿着每一列取最小值
   axis=1:沿着每一行取最大值

            
              A.min(axis=0)
A.min(axis=1)
            
          

  axis=0的结果:

            
              array([0, 1, 2, 3])
            
          

axis=1的结果:

            
              array([ 0,  4,  8, 12, 16, 20])
            
          

像这样的函数还有很多,不再一一介绍,不过都是按照axis=1按列操作,axis=0按行操作的规律进行的。

矩阵元素的选取:

            
              a = np.arange(10)**2
array([ 0,  1,  4,  9, 16, 25, 36, 49, 64, 81], dtype=int32)
            
          

选取某个位置的元素:

            
              a[5]
25
            
          

从结果是25可以看出,下标是从0开始计数。

选取某几个元素:

从结果可以看出,选取的元素是从第一个参数开始,第二个参数为止且不包含第二个参数位置的元素。

            
              a[1:3]
array([1, 4], dtype=int32)
            
          

下面介绍一个大家在复制矩阵时有可能遇到的坑~

            
              a_slice = a[0:5]
array([100, 100, 100,   9,  16], dtype=int32)
            
          

这里选取了0-4位置的元素变成一个新的array,下面对此array进行操作:

可以看到该操作,也同样对a产生了影响,因为,当选取部分np array的时候,我们创建了一个view,也就是说,我们没有copy之前的值,而是直接改了原来的array。

            
              a_slice[0]=222
a_slice
array([222, 100, 100,   9,  16], dtype=int32)
a
array([222, 100, 100,   9,  16,  25,  36,  49,  64,  81], dtype=int32)
            
          

那么,如果我们不想改变之前的array怎么办呢?

这时,就用到了copy函数,是指将数据copy到新的array中并不对原array产生影响。

            
              a_slice_2 = a[0:5].copy()
a_slice_2[1]=222
array([222, 222, 100,   9,  16], dtype=int32)
            
          

下面总结一下用方程建矩阵,及多维矩阵的选取和切片:

            
              def f(x,y):
    return 4 * x +y
b = np.fromfunction(f,(3,2),dtype=int)
b
            
          

这里我们就自定义了一个函数f,下面用fromfunction方法创建一个三行两列的数组

结果为:

            
              array([[0, 1],
       [4, 5],
       [8, 9]])
            
          

array的选取:

[:]:仅针对行的操作

[:,]:对行和列的选取

            
              #全选
b[:]
array([[0, 1],
       [4, 5],
       [8, 9]])
#从某行开始选到某行结束
b[:1]
array([[0, 1]])
#选取所有行和第一列
b[:,1]
array([1, 5, 9])
#选取行
b[1]
array([4, 5])
#选取某个位置的元素
b[1,0]
4
            
          

这里再说一些shape函数的用法,之前博文中也有提到:

这里0指的是该矩阵有几行,1代表这个矩阵有几列

            
              b.shape[0]
3
b.shape[1]
2
            
          

矩阵的转至,先举一个一般的矩阵的转至,以上面的b矩阵为例:

            
              b.T
array([[0, 4, 8],
       [1, 5, 9]])
            
          

那么对于堆矩阵,如何转至呢?

首先创建一个堆:

            
              c=np.array([[[1,2,3,0],[3,4,5,2]]])
c.shape
            
          

这是一个一堆两行四列的矩阵

            
              array([[[1, 2, 3, 0],
        [3, 4, 5, 2]]])
(1, 2, 4)
            
          

直接使用T转至函数:

            
              c.T
            
          

结果为:

            
              array([[[1],
        [3]],

       [[2],
        [4]],

       [[3],
        [5]],

       [[0],
        [2]]])
            
          

看下转至后的类型:可以看到是原来的每列变成堆,所以变成4堆,整体变为4堆两行一列

            
              c.T.shape
            
          
            
              (4, 2, 1)
            
          

这时候就有一个进阶函数,可以指定转变的方式

            
              c.transpose(0,2,1)
            
          

三个参数的意思是,第一个维度不变,后面两个维度交换位置,那形状就变成了一堆四行两列

结果为:

            
              array([[[1, 3],
        [2, 4],
        [3, 5],
        [0, 2]]])
            
          

求逆矩阵

            
              a1 = np.mat([[3,4],[2,16]])
np.linalg.inv(np.dot(a1.T,a1))
            
          

结果为:

            
              matrix([[ 0.17    , -0.0275  ],
        [-0.0275  ,  0.008125]])
            
          

比较两个矩阵是否相同:

            
              a = np.array([[1.,2.],[3.,4.]])
ainv = np.linalg.inv(a)
np.allclose(np.dot(a,ainv),np.eye(2))
            
          

结果为:

            
              True
            
          

以上就是一些介绍啦~


更多文章、技术交流、商务合作、联系博主

微信扫码或搜索:z360901061

微信扫一扫加我为好友

QQ号联系: 360901061

您的支持是博主写作最大的动力,如果您喜欢我的文章,感觉我的文章对您有帮助,请用微信扫描下面二维码支持博主2元、5元、10元、20元等您想捐的金额吧,狠狠点击下面给点支持吧,站长非常感激您!手机微信长按不能支付解决办法:请将微信支付二维码保存到相册,切换到微信,然后点击微信右上角扫一扫功能,选择支付二维码完成支付。

【本文对您有帮助就好】

您的支持是博主写作最大的动力,如果您喜欢我的文章,感觉我的文章对您有帮助,请用微信扫描上面二维码支持博主2元、5元、10元、自定义金额等您想捐的金额吧,站长会非常 感谢您的哦!!!

发表我的评论
最新评论 总共0条评论