zoukankan      html  css  js  c++  java
  • NumPy-快速处理数据--矩阵运算

    本文摘自《用Python做科学计算》,版权归原作者所有。

    1. NumPy-快速处理数据--ndarray对象--数组的创建和存取

    2. NumPy-快速处理数据--ndarray对象--多维数组的存取、结构体数组存取、内存对齐、Numpy内存结构

    3. NumPy-快速处理数据--ufunc运算--广播--ufunc方法

    接下来介绍矩阵运算

    Numpy默认不使用矩阵运算,如果希望对数组进行矩阵运算的话需要调用相应的函数

    matrix 对象

    numpy库提供了matrix类,使用matrix类创建的是矩阵对象,它们的加减乘除运算缺省采用矩阵方式计算,因此用法和matlab十分类似。但是由于NumPy中同时存在ndarray和matrix对象,因此用户很容易将两者弄混。这有违Python的“显式优于隐式”的原则,因此并不推荐在较复杂的程序中使用matrix。下面是使用matrix的一个例子:

     1 >>> import numpy as np
     2 >>> a = np.matrix([[1,2,3],[5,5,6],[7,9,9]])
     3 >>> a**-1     # a 的逆矩阵
     4 matrix([[-0.6       ,  0.6       , -0.2       ],
     5         [-0.2       , -0.8       ,  0.6       ],
     6         [ 0.66666667,  0.33333333, -0.33333333]])
     7 >>> a * a**-1 # a与a的逆矩阵的乘积,结果是单位阵
     8 matrix([[  1.00000000e+00,   0.00000000e+00,   0.00000000e+00],
     9         [  4.44089210e-16,   1.00000000e+00,   4.44089210e-16],
    10         [  0.00000000e+00,  -4.44089210e-16,   1.00000000e+00]])

    如果不使用matrix 对象,而把二维数组看作是矩阵的话,就需要使用dot函数进行计算。对于二维数组,它计算的是矩阵乘积,对于一维数组,它计算的是其点积。当需要将一维数组当作列矢量或者行矢量进行矩阵运算时,推荐先使用reshape或者shape函数将一维数组转换为二维数组:

     1 >>> a = np.array([1, 2, 3])
     2 >>> a.shape#a是一维数组
     3 (3,)
     4 >>> a.shape = (-1, 1)#使用shape直接修改a的维数
     5 >>> a
     6 array([[1],
     7        [2],
     8        [3]])
     9 >>> a.reshape(1, -1) #使用reshape也可以,但是他的返回值改变a的shape,而a本身不变
    10 array([[1, 2, 3]])
    11 >>> a
    12 array([[1],
    13        [2],
    14        [3]])
    • dot :对于两个一维的数组,计算的是这两个数组对应下标元素的乘积和(数学上称之为内积);对于二维数组,计算的是两个数组的矩阵乘积;对于多维数组,它的通用计算公式如下,即结果数组中的每个元素都是:数组a的最后一维上的所有元素与数组b的倒数第二位上的所有元素的乘积和:

    dot(a, b)[i,j,k,m] = sum(a[i,j,:] * b[k,:,m])

    两个三维数组相乘

     1 >>> a = np.arange(12).reshape(2,3,2)
     2 >>> a
     3 array([[[ 0,  1],
     4         [ 2,  3],
     5         [ 4,  5]],
     6 
     7        [[ 6,  7],
     8         [ 8,  9],
     9         [10, 11]]])
    10 >>> b = np.arange(12,24).reshape(2,2,3)
    11 >>> b
    12 array([[[12, 13, 14],
    13         [15, 16, 17]],
    14 
    15        [[18, 19, 20],
    16         [21, 22, 23]]])
    17 >>> c = np.dot(a,b)
    18 >>> c
    19 array([[[[ 15,  16,  17],
    20          [ 21,  22,  23]],
    21 
    22         [[ 69,  74,  79],
    23          [ 99, 104, 109]],
    24 
    25         [[123, 132, 141],
    26          [177, 186, 195]]],
    27 
    28 
    29        [[[177, 190, 203],
    30          [255, 268, 281]],
    31 
    32         [[231, 248, 265],
    33          [333, 350, 367]],
    34 
    35         [[285, 306, 327],
    36          [411, 432, 453]]]])
    37 >>> c.shape
    38 (2, 3, 2, 3)

    dot乘积的结果c可以看做是数组a, b的多个子矩阵的乘积:

    1 >>> np.alltrue( c[0,:,0,:] == np.dot(a[0],b[0]) )
    2 True
    3 >>> np.alltrue( c[1,:,0,:] == np.dot(a[1],b[0]) )
    4 True
    5 >>> np.alltrue( c[0,:,1,:] == np.dot(a[0],b[1]) )
    6 True
    7 >>> np.alltrue( c[1,:,1,:] == np.dot(a[1],b[1]) )
    8 True
    • inner : 和dot乘积一样,对于两个一维数组,计算的是这两个数组对应下标元素的乘积和;对于多维数组,它计算的结果数组中的每个元素都是:数组a和b的最后一维的内积,因此数组a和b的最后一维的长度必须相同:

    1 inner(a, b)[i,j,k,m] = sum(a[i,j,:]*b[k,m,:])
     1 >>> a = np.arange(12).reshape(2,3,2)
     2 >>> b = np.arange(12,24).reshape(2,3,2)
     3 >>> c = np.inner(a,b)
     4 >>> c.shape
     5 (2, 3, 2, 3)
     6 >>> c[0,0,0,0] == np.inner(a[0,0],b[0,0])
     7 True
     8 >>> c[0,1,1,0] == np.inner(a[0,1],b[1,0])
     9 True
    10 >>> c[1,2,1,2] == np.inner(a[1,2],b[1,2])
    11 True
    • outer : 只按照一维数组进行计算,如果传入参数是多维数组,则先将此数组展平为一维数组之后再进行运算。outer乘积计算的列向量和行向量的矩阵乘积:

    1 >>> np.outer([1,2,3],[4,5,6,7])
    2 array([[ 4,  5,  6,  7],
    3        [ 8, 10, 12, 14],
    4        [12, 15, 18, 21]])

    矩阵中更高级的一些运算可以在NumPy的线性代数子库linalg中找到。例如inv函数计算逆矩阵,solve函数可以求解多元一次方程组。下面是solve函数的一个例子:

    1 >>> a = np.random.rand(10,10)
    2 >>> b = np.random.rand(10)
    3 >>> x = np.linalg.solve(a,b)

    solve函数有两个参数a和b。a是一个N*N的二维数组,而b是一个长度为N的一维数组,solve函数找到一个长度为N的一维数组x,使得a和x的矩阵乘积正好等于b,数组x就是多元一次方程组的解。

    http://www.cnblogs.com/moon1992/
  • 相关阅读:
    【最短路】BAPC2014 B Button Bashing (Codeforces GYM 100526)
    【链表】【模拟】Codeforces 706E Working routine
    【数论】【扩展欧几里得】Codeforces 710D Two Arithmetic Progressions
    【动态规划】【最短路】Codeforces 710E Generate a String
    【模拟】Codeforces 710C Magic Odd Square
    【模拟】Codeforces 710B Optimal Point on a Line
    【模拟】Codeforces 710A King Moves
    【模拟】Codeforces 705A Hulk
    【模拟】Codeforces 705B Spider Man
    【模拟】Codeforces 704A & 705C Thor
  • 原文地址:https://www.cnblogs.com/moon1992/p/4948793.html
Copyright © 2011-2022 走看看