• 数据分析----numpy快速入门


    【原文链接】

    一、numpy的安装

    若直接使用系统的python环境,则使用如下命令安装

    pip install numpy
    
    • 1

    若使用pipenv工具创建的虚拟环境,则使用如下命令:

    pipenv install numpy
    
    • 1

    二、Numpy中矩阵array的基本属性

    • ndim:维数
      比如3x4的矩阵,它的ndim为2

    • shape:表示几行几列,用元组表示
      比如3x4矩阵,它的shape为(3,4)

    • size: 元素的总的数量
      比如3x4的矩阵,它的size为12

    • dtype:元素的类型
      可以直接使用python的中类型,numpy也提供了一些类型比如numpy.int32, numpy.int16, numpy.float64 等

    • itemsize: 元素的大小
      每个元素占用的内存,单位是字节,比如类型时int64,则itemsize为8个字节,相当于是dtype.itemsize

    实例如下,其中arr=np.arange(12).reshape((3,4))是用于创建一个3x4的矩阵,元素是0-11,后面会继续详解如何创建矩阵的,这里是为了演示矩阵的属性

    >>> import numpy as np
    >>> arr=np.arange(12).reshape((3,4))
    >>> arr
    array([[ 0,  1,  2,  3],
           [ 4,  5,  6,  7],
           [ 8,  9, 10, 11]])
    >>> arr.ndim
    2
    >>> arr.shape
    (3, 4)
    >>> arr.dtype
    dtype('int32')
    >>> arr.dtype.name
    'int32'
    >>> arr.size
    12
    >>> arr.itemsize
    4
    >>> type(arr)
    <class 'numpy.ndarray'>
    >>>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    三、创建矩阵

    3.1 通过使用Python的list或者tuple来创建矩阵

    如下,分别使用一维列表,一维元组,二维列表,二维元组创建矩阵

    >>> import numpy as np
    >>> arr=np.array([1,2,3])
    >>> arr
    array([1, 2, 3])
    >>> arr=np.array((1,2,3))
    >>> arr
    array([1, 2, 3])
    >>> arr=np.array([[1,2,3],[4,5,6]])
    >>> arr
    array([[1, 2, 3],
           [4, 5, 6]])
    >>> arr=np.array(((1,2,3),(4,5,6)))
    >>> arr
    array([[1, 2, 3],
           [4, 5, 6]])
    >>>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    这里需要注意一下,np.array的参数是列表或元素,如果直接给定几个元素时不可以的,如下是一个初学者常见的错误

    >>> import numpy as np
    >>> arr=np.array(1,2,3,4)
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    TypeError: array() takes from 1 to 2 positional arguments but 4 were given
    
    • 1
    • 2
    • 3
    • 4
    • 5

    正确的应该如下:

    >>> import numpy as np
    >>> arr=np.array([1,2,3,4])
    >>> arr
    array([1, 2, 3, 4])
    
    • 1
    • 2
    • 3
    • 4

    此外创建矩阵的时候,还可以指定数据的类型,下面先看一下不指定数据类型时,默认的数据类型,当然这个是会和计算机平台有关的,如下,默认情况下是32位的int类型

    >>> import numpy as np
    >>> arr=np.array([1,2,3])
    >>> arr
    array([1, 2, 3])
    >>> arr.dtype
    dtype('int32')
    >>>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    如下,即可通过dtype参数指定矩阵元素的类型

    >>> import numpy as np
    >>> arr=np.array([1,2,3],dtype=np.int64)
    >>> arr
    array([1, 2, 3], dtype=int64)
    >>> arr.dtype
    dtype('int64')
    >>>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    3.2 通过常用的基本函数创建矩阵

    常用的函数如下

    • zeros:创建所有元素均为0的矩阵
    • ones:创建所有元素都为1的矩阵
    • empty:创建元素随机的矩阵,默认情况下empty函数创建的元素类型为float64,当然可以也可以通过dtype参数指定类型。
    • arange:类似于python中range的函数,可以通过指定初始值和结束值以及步长来生成等差数列的,当然可以通过reshape函数对生成的一维等差数列转换为多维矩阵。
    • linspace:通过指定起始值和结束值以及生成的数字的个数,然后自动进行等差分割,同样可以通过reshape函数对生成的一维列表转换为多维矩阵

    举例如下:

    >>> import numpy as np
    >>> arr=np.zeros((3,4))
    >>> arr
    array([[0., 0., 0., 0.],
           [0., 0., 0., 0.],
           [0., 0., 0., 0.]])
    >>> arr=np.ones((3,4))
    >>> arr
    array([[1., 1., 1., 1.],
           [1., 1., 1., 1.],
           [1., 1., 1., 1.]])
    >>> arr=np.empty((3,4))
    >>> arr
    array([[1., 1., 1., 1.],
           [1., 1., 1., 1.],
           [1., 1., 1., 1.]])
    >>> arr=np.empty((3,4),dtype=np.int32)
    >>> arr
    array([[ 0,  1,  2,  3],
           [ 4,  5,  6,  7],
           [ 8,  9, 10, 11]])
    >>> arr=np.arange(0,12,1).reshape((3,4))
    >>> arr
    array([[ 0,  1,  2,  3],
           [ 4,  5,  6,  7],
           [ 8,  9, 10, 11]])
    >>> arr=np.arange(0,24,2).reshape((3,4))
    >>> arr
    array([[ 0,  2,  4,  6],
           [ 8, 10, 12, 14],
           [16, 18, 20, 22]])
    >>> arr=np.linspace(1,100,12).reshape((3,4))
    >>> arr
    array([[  1.,  10.,  19.,  28.],
           [ 37.,  46.,  55.,  64.],
           [ 73.,  82.,  91., 100.]])
    >>>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37

    四、打印矩阵

    numpy在打印多维矩阵的时候,会遵循如下布局

    • 最后一个维度从左到右打印
    • 倒数第二个维度从上到下打印
    • 剩下的都是从上到下打印,并且每个维度之间使用一个空行分隔

    如下为分表打印一维、二维、三维矩阵

    >>> import numpy as np
    >>> arr=np.arange(6)
    >>> print(arr)
    [0 1 2 3 4 5]
    >>> b=np.arange(12).reshape((3,4))
    >>> print(b)
    [[ 0  1  2  3]
     [ 4  5  6  7]
     [ 8  9 10 11]]
    >>> c=np.arange(24).reshape((2,3,4))
    >>> print(c)
    [[[ 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
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    如果矩阵元素特别多,则numpy会只个保留角落的部分,中间的则使用 … 代替,如下:

    >>> import numpy as np
    >>> arr=np.arange(10000)
    >>> print(arr)
    [   0    1    2 ... 9997 9998 9999]
    >>> arr=np.arange(10000).reshape((100,100))
    >>> print(arr)
    [[   0    1    2 ...   97   98   99]
     [ 100  101  102 ...  197  198  199]
     [ 200  201  202 ...  297  298  299]
     ...
     [9700 9701 9702 ... 9797 9798 9799]
     [9800 9801 9802 ... 9897 9898 9899]
     [9900 9901 9902 ... 9997 9998 9999]]
    >>>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    当然如果就是要打印全部元素也是可以设置,通过使用set_printoptions来控制

    np.set_printoptions(threshold=sys.maxsize)
    
    • 1

    五、基本运算

    基本的加减乘除乘方就是矩阵的元素与元素之间进行加减乘除乘方,如下

    >>> import numpy as np
    >>> a=np.array([1,2,3,4])
    >>> b=np.arange(4)
    >>> a
    array([1, 2, 3, 4])
    >>> b
    array([0, 1, 2, 3])
    >>> a+b
    array([1, 3, 5, 7])
    >>> a-b
    array([1, 1, 1, 1])
    >>> a*b
    array([ 0,  2,  6, 12])
    >>> b/a
    array([0.        , 0.5       , 0.66666667, 0.75      ])
    >>> a>0
    array([ True,  True,  True,  True])
    >>> a**2
    array([ 1,  4,  9, 16])
    >>> b>2
    array([False, False, False,  True])
    >>> np.sin(a)
    array([ 0.84147098,  0.90929743,  0.14112001, -0.7568025 ])
    >>> np.cos(a)
    array([ 0.54030231, -0.41614684, -0.9899925 , -0.65364362])
    >>> np.tan(a)
    array([ 1.55740772, -2.18503986, -0.14254654,  1.15782128])
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28

    矩阵的点乘使用dot或者使用@符号,如下:

    >>> a=np.array([[1,1],[0,1]])
    >>> b=np.array([[2,0],[3,4]])
    >>> a
    array([[1, 1],
           [0, 1]])
    >>> b
    array([[2, 0],
           [3, 4]])
    >>> a*b
    array([[2, 0],
           [0, 4]])
    >>> a@b
    array([[5, 4],
           [3, 4]])
    >>> a.dot(b)
    array([[5, 4],
           [3, 4]])
    >>> np.dot(a,b)
    array([[5, 4],
           [3, 4]])
    >>>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    有些运算符比如 +=或*=,会直接对已有的矩阵做处理而不是创建一个新的矩阵,如下,其中 np.random.default_rng(1)是默认的随机数生成器

    >>> import numpy as np
    >>> rng=np.random.default_rng(1)
    >>> a=np.ones((2,3),dtype=np.int32)
    >>> b=rng.random((2,3))
    >>> a
    array([[1, 1, 1],
           [1, 1, 1]])
    >>> b
    array([[0.51182162, 0.9504637 , 0.14415961],
           [0.94864945, 0.31183145, 0.42332645]])
    >>> a*=3
    >>> a
    array([[3, 3, 3],
           [3, 3, 3]])
    >>> b+=a
    >>> b
    array([[3.51182162, 3.9504637 , 3.14415961],
           [3.94864945, 3.31183145, 3.42332645]])
    >>> a+=b
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    numpy.core._exceptions._UFuncOutputCastingError: Cannot cast ufunc 'add' output from dtype('float64') to dtype('int32') with casting rule 'same_kind'
    >>>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23

    当运算中涉及多种类型时,结果会按照向上转换的原则,如下:

    >>> import numpy as np
    >>> a=np.ones(3,dtype=np.int32)
    >>> b=np.linspace(0,np.pi,3)
    >>> a
    array([1, 1, 1])
    >>> b
    array([0.        , 1.57079633, 3.14159265])
    >>> c=a+b
    >>> c
    array([1.        , 2.57079633, 4.14159265])
    >>> b.dtype
    dtype('float64')
    >>> c.dtype
    dtype('float64')
    >>> d=np.exp(c*1j)
    >>> d
    array([ 0.54030231+0.84147098j, -0.84147098+0.54030231j,
           -0.54030231-0.84147098j])
    >>> d.dtype
    dtype('complex128')
    >>>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    计算矩阵所有元素的和、最大值、最小值函数,即sum、max和min,如下:

    >>> import numpy as np
    >>> a=np.arange(12).reshape((3,4))
    >>> a
    array([[ 0,  1,  2,  3],
           [ 4,  5,  6,  7],
           [ 8,  9, 10, 11]])
    >>> a.sum()
    66
    >>> np.sum(a)
    66
    >>> a.max()
    11
    >>> np.max(a)
    11
    >>> a.min()
    0
    >>> np.min(a)
    0
    >>>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    通过axis参数可以按行或按列计算元素和、最大值和最小值,当axis=0时,表示按列,当axis=1时,表示按行,如下

    >>> import numpy as np
    >>> a=np.arange(12).reshape((3,4))
    >>> a
    array([[ 0,  1,  2,  3],
           [ 4,  5,  6,  7],
           [ 8,  9, 10, 11]])
    >>> a.sum(axis=0)
    array([12, 15, 18, 21])
    >>> np.sum(a,axis=0)
    array([12, 15, 18, 21])
    >>> a.sum(axis=1)
    array([ 6, 22, 38])
    >>> np.sum(a,axis=1)
    array([ 6, 22, 38])
    >>> a.max(axis=0)
    array([ 8,  9, 10, 11])
    >>> np.max(a,axis=0)
    array([ 8,  9, 10, 11])
    >>> a.max(axis=1)
    array([ 3,  7, 11])
    >>> np.max(a,axis=1)
    array([ 3,  7, 11])
    >>> a.min(axis=0)
    array([0, 1, 2, 3])
    >>> np.min(a,axis=0)
    array([0, 1, 2, 3])
    >>> a.min(axis=1)
    array([0, 4, 8])
    >>> np.min(a,axis=1)
    array([0, 4, 8])
    >>>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31

    六、通用函数

    常用的通用函数如下:

    • sin
    • cos
    • exp
    • sqrt
    • add
    • all
    • any
    • apply_along_axis
    • argmax
    • argmin
    • argsort
    • average
    • bincount
    • ceil
    • clip
    • conj
    • corrcoef
    • cov
    • cross
    • cumprod
    • cumsum
    • diff
    • dot
    • floor
    • inner
    • invert
    • lexsort
    • max
    • maximum
    • mean
    • median
    • min
    • minimum
    • nonzero
    • outer
    • prod
    • re
    • round
    • sort
    • std
    • sum
    • trace
    • transpose
    • var
    • vdot
    • vectorize
    • where

    举例如下:

    >>> import numpy as np
    >>> a=np.arange(3)
    >>> a
    array([0, 1, 2])
    >>> np.exp(a)
    array([1.        , 2.71828183, 7.3890561 ])
    >>> np.sqrt(a)
    array([0.        , 1.        , 1.41421356])
    >>> b=np.array([4,5,6])
    >>> b
    array([4, 5, 6])
    >>> np.add(a,b)
    array([4, 6, 8])
    >>>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    七、索引、切片和迭代

    7.1 一维矩阵的索引、切片和迭代使用方法

    一维矩阵的索引、切片和迭代使用方法像python中列表的索引、切片、迭代一样,如下:

    >>> import numpy as np
    >>> a=np.arange(10)
    >>> a
    array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
    >>> a[2]
    2
    >>> a[2:5]
    array([2, 3, 4])
    >>> a[:6:2]
    array([0, 2, 4])
    >>> a[::-1]
    array([9, 8, 7, 6, 5, 4, 3, 2, 1, 0])
    >>> for i in a:
    ...    print(i)
    ...
    0
    1
    2
    3
    4
    5
    6
    7
    8
    9
    >>>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26

    7.2 多维矩阵的索引、切片和迭代

    多维矩阵的索引、切片和迭代,主要区别就是每个维度使用一个索引,中间用逗号隔开,如下:

    >>> import numpy as np
    >>> a=np.arange(20).reshape((5,4))
    >>> a
    array([[ 0,  1,  2,  3],
           [ 4,  5,  6,  7],
           [ 8,  9, 10, 11],
           [12, 13, 14, 15],
           [16, 17, 18, 19]])
    >>> a[2,3]
    11
    >>> a[0:4,1]
    array([ 1,  5,  9, 13])
    >>> a[:,1]
    array([ 1,  5,  9, 13, 17])
    >>> a[1:3:,:]
    array([[ 4,  5,  6,  7],
           [ 8,  9, 10, 11]])
    >>> for elem in a[:,1]:
    ...     print(elem)
    ...
    1
    5
    9
    13
    17
    >>> for elem in a[:,:]:
    ...     print(elem)
    ...
    [0 1 2 3]
    [4 5 6 7]
    [ 8  9 10 11]
    [12 13 14 15]
    [16 17 18 19]
    >>>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34

    当提供的索引的数量少于矩阵的维数,则后续默认为:,如下a[2],就相当于是a[2,:]

    >>> import numpy as np
    >>> a=np.arange(20).reshape((4,5))
    >>> a
    array([[ 0,  1,  2,  3,  4],
           [ 5,  6,  7,  8,  9],
           [10, 11, 12, 13, 14],
           [15, 16, 17, 18, 19]])
    >>> a[2]
    array([10, 11, 12, 13, 14])
    >>>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    当多维矩阵时,可以通过使用三个点来代替其他维数,比如如下假设a是一个五维矩阵,则:

    • a[1,2,…]就相当于a[1,2,:,:,:]
    • a[…,3]就相当于a[:,:,:,:,3]
    • a[4,…,5,:]就相当于a[4,:,:,5,:]

    如下

    >>> import numpy as np
    >>> a=np.arange(24).reshape((2,3,4))
    >>> a
    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]]])
    >>> a[1,...]
    array([[12, 13, 14, 15],
           [16, 17, 18, 19],
           [20, 21, 22, 23]])
    >>> a[1,:,:]
    array([[12, 13, 14, 15],
           [16, 17, 18, 19],
           [20, 21, 22, 23]])
    >>> a[...,2]
    array([[ 2,  6, 10],
           [14, 18, 22]])
    >>> a[:,:,2]
    array([[ 2,  6, 10],
           [14, 18, 22]])
    >>>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25

    当对多维矩阵进行遍历的时候通常按照第一个维度进行遍历,当希望对每个元素进行遍历的时候,可以使用flat属性,如下

    >>> import numpy as np
    >>> a=np.arange(12).reshape((3,4))
    >>> a
    array([[ 0,  1,  2,  3],
           [ 4,  5,  6,  7],
           [ 8,  9, 10, 11]])
    >>> for elem in a:
    ...     print(elem)
    ...
    [0 1 2 3]
    [4 5 6 7]
    [ 8  9 10 11]
    >>> for elem in a.flat:
    ...     print(elem)
    ...
    0
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    >>>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28

    八、对矩阵shape的操作

    对于矩阵以下三个方法不会改变矩阵的shape原有的值

    • ravel:将矩阵展开为一维矩阵
    • T:矩阵转秩
    • reshape:重新调整shape,但不会修改原有shape

    如下

    >>> import numpy as np
    >>> a=np.arange(12).reshape((3,4))
    >>> a
    array([[ 0,  1,  2,  3],
           [ 4,  5,  6,  7],
           [ 8,  9, 10, 11]])
    >>> b=a.ravel()
    >>> a
    array([[ 0,  1,  2,  3],
           [ 4,  5,  6,  7],
           [ 8,  9, 10, 11]])
    >>> b
    array([ 0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11])
    >>> c=a.reshape(6,2)
    >>> a
    array([[ 0,  1,  2,  3],
           [ 4,  5,  6,  7],
           [ 8,  9, 10, 11]])
    >>> c
    array([[ 0,  1],
           [ 2,  3],
           [ 4,  5],
           [ 6,  7],
           [ 8,  9],
           [10, 11]])
    >>> d=a.T
    >>> a
    array([[ 0,  1,  2,  3],
           [ 4,  5,  6,  7],
           [ 8,  9, 10, 11]])
    >>> d
    array([[ 0,  4,  8],
           [ 1,  5,  9],
           [ 2,  6, 10],
           [ 3,  7, 11]])
    >>> a.shape
    (3, 4)
    >>> a.T.shape
    (4, 3)
    >>> e=a.reshape((6,2))
    >>> a
    array([[ 0,  1,  2,  3],
           [ 4,  5,  6,  7],
           [ 8,  9, 10, 11]])
    >>> e
    array([[ 0,  1],
           [ 2,  3],
           [ 4,  5],
           [ 6,  7],
           [ 8,  9],
           [10, 11]])
    >>>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52

    若想对原有矩阵的shape进行调整,可以使用resize函数,如下,可以发现resize函数是直接对原来的矩阵进行调整,同时没有返回值,即在下面的例子中b为空

    >>> import numpy as np
    >>> a=np.arange(12).reshape((3,4))
    >>> a
    array([[ 0,  1,  2,  3],
           [ 4,  5,  6,  7],
           [ 8,  9, 10, 11]])
    >>> b=a.resize(6,2)
    >>> a
    array([[ 0,  1],
           [ 2,  3],
           [ 4,  5],
           [ 6,  7],
           [ 8,  9],
           [10, 11]])
    >>> b
    >>>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    再使用reshape函数的时候,如果某一个维度设置为-1,则表示此维度自动计算,如下

    >>> import numpy as np
    >>> a=np.arange(12).reshape((3,4))
    >>> a
    array([[ 0,  1,  2,  3],
           [ 4,  5,  6,  7],
           [ 8,  9, 10, 11]])
    >>> b=a.reshape(6,-1)
    >>> a
    array([[ 0,  1,  2,  3],
           [ 4,  5,  6,  7],
           [ 8,  9, 10, 11]])
    >>> b
    array([[ 0,  1],
           [ 2,  3],
           [ 4,  5],
           [ 6,  7],
           [ 8,  9],
           [10, 11]])
    >>>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    九、不同矩阵之间的堆叠

    不同矩阵之间的水平堆叠和垂直堆叠,如下

    >>> import numpy as np
    >>> a=np.arange(4).reshape((2,2))
    >>> b=np.arange(4,8).reshape((2,2))
    >>> a
    array([[0, 1],
           [2, 3]])
    >>> b
    array([[4, 5],
           [6, 7]])
    >>> np.vstack((a,b))
    array([[0, 1],
           [2, 3],
           [4, 5],
           [6, 7]])
    >>> np.hstack((a,b))
    array([[0, 1, 4, 5],
           [2, 3, 6, 7]])
    >>>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    column_stack只有在二维矩阵时才相当于hstack,而row_stack就是vstack的别名,如下

    >>> import numpy as np
    >>> a=np.arange(3)
    >>> b=np.arange(3,6)
    >>> a
    array([0, 1, 2])
    >>> b
    array([3, 4, 5])
    >>> np.column_stack((a,b))
    array([[0, 3],
           [1, 4],
           [2, 5]])
    >>> np.hstack((a,b))
    array([0, 1, 2, 3, 4, 5])
    >>> np.row_stack((a,b))
    array([[0, 1, 2],
           [3, 4, 5]])
    >>> np.vstack((a,b))
    array([[0, 1, 2],
           [3, 4, 5]])
    >>> a=np.arange(4).reshape((2,2))
    >>> b=np.arange(4,8).reshape((2,2))
    >>> a
    array([[0, 1],
           [2, 3]])
    >>> b
    array([[4, 5],
           [6, 7]])
    >>> np.column_stack((a,b))
    array([[0, 1, 4, 5],
           [2, 3, 6, 7]])
    >>> np.hstack((a,b))
    array([[0, 1, 4, 5],
           [2, 3, 6, 7]])
    >>> np.row_stack((a,b))
    array([[0, 1],
           [2, 3],
           [4, 5],
           [6, 7]])
    >>> np.vstack((a,b))
    array([[0, 1],
           [2, 3],
           [4, 5],
           [6, 7]])
    >>> np.column_stack is np.hstack
    False
    >>> np.row_stack is np.vstack
    True
    >>>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48

    十、通过newaxis为现有矩阵增加一个维度

    简单来说就是将newaxis参数放在哪个位置,哪个位置对应的维度就设置为1,举例如下

    >>> import numpy as np
    >>> a=np.array([1,2,3,4])
    >>> a
    array([1, 2, 3, 4])
    >>> a.shape
    (4,)
    >>> b=a[:,np.newaxis]
    >>> b
    array([[1],
           [2],
           [3],
           [4]])
    >>> b.shape
    (4, 1)
    >>> c=a[np.newaxis,:]
    >>> c
    array([[1, 2, 3, 4]])
    >>> c.shape
    (1, 4)
    >>>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    十一、将矩阵切割为许多更小的矩阵

    分割矩阵可以使用hsplit和vsplit,参数可以是一个数字,表示将矩阵按照列或者行分为n个小矩阵,也可以是一个元素,表示在元组中每一个数字对应的列或行之后进行分割,如下

    >>> import numpy as np
    >>> a=np.arange(24).reshape((4,6))
    >>> a
    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]])
    >>> np.hsplit(a,3)  # 表示将a按照列分为3个小矩阵
    [array([[ 0,  1],
           [ 6,  7],
           [12, 13],
           [18, 19]]), array([[ 2,  3],
           [ 8,  9],
           [14, 15],
           [20, 21]]), array([[ 4,  5],
           [10, 11],
           [16, 17],
           [22, 23]])]
    >>> np.vsplit(a,2) # 表示将a按照行分为2个小矩阵
    [array([[ 0,  1,  2,  3,  4,  5],
           [ 6,  7,  8,  9, 10, 11]]), array([[12, 13, 14, 15, 16, 17],
           [18, 19, 20, 21, 22, 23]])]
    >>> np.hsplit(a,(2,4)) # 表示将a按照列在第2列和第4列后面分割
    [array([[ 0,  1],
           [ 6,  7],
           [12, 13],
           [18, 19]]), array([[ 2,  3],
           [ 8,  9],
           [14, 15],
           [20, 21]]), array([[ 4,  5],
           [10, 11],
           [16, 17],
           [22, 23]])]
    >>> np.vsplit(a,(1,3)) # 表示将a按照行在第一行和第三行后面分割
    [array([[0, 1, 2, 3, 4, 5]]), array([[ 6,  7,  8,  9, 10, 11],
           [12, 13, 14, 15, 16, 17]]), array([[18, 19, 20, 21, 22, 23]])]
    >>>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37

    十二、拷贝和视图

    12.1 没有拷贝发生场景

    当直接赋值或者是在函数中传递对象,都不会发生拷贝的现象,函数传递参数因为在python中传递的是对象的引用,所以不会发生拷贝,如下

    >>> import numpy as mp
    >>> a=np.array([1,2,3,4])
    >>> b=a
    >>> a
    array([1, 2, 3, 4])
    >>> b
    array([1, 2, 3, 4])
    >>> b is a
    True
    >>> def f(x):
    ...     print(id(x))
    ...
    >>> id(a)
    2211569938384
    >>> f(a)
    2211569938384
    >>>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    12.2 视图或浅拷贝

    通过view函数创建的视图实质上是一个浅拷贝,对拷贝后的对象进行resize不会影响源对象,但是修改值的操作会让源矩阵对应的值同步修改,此外切片本质上也是产生一个新的视图,如下

    >>> import numpy as np
    >>> a=np.arange(12).reshape((3,4))
    >>> a
    array([[ 0,  1,  2,  3],
           [ 4,  5,  6,  7],
           [ 8,  9, 10, 11]])
    >>> b=a.view()
    >>> b
    array([[ 0,  1,  2,  3],
           [ 4,  5,  6,  7],
           [ 8,  9, 10, 11]])
    >>> id(a)
    2211558280336
    >>> id(b)
    2211569938192
    >>> b is a
    False
    >>> b.base is a
    False
    >>> b.flags.owndata
    False
    >>> b.resize((2,6))
    >>> b
    array([[ 0,  1,  2,  3,  4,  5],
           [ 6,  7,  8,  9, 10, 11]])
    >>> a
    array([[ 0,  1,  2,  3],
           [ 4,  5,  6,  7],
           [ 8,  9, 10, 11]])
    >>> b[0,0]=100
    >>> b
    array([[100,   1,   2,   3,   4,   5],
           [  6,   7,   8,   9,  10,  11]])
    >>> a
    array([[100,   1,   2,   3],
           [  4,   5,   6,   7],
           [  8,   9,  10,  11]])
    >>> c=a[:,0:2]
    >>> c
    array([[100,   1],
           [  4,   5],
           [  8,   9]])
    >>> c.flags.owndata
    False
    >>> c[0,0]=10000
    >>> c
    array([[10000,     1],
           [    4,     5],
           [    8,     9]])
    >>> a
    array([[10000,     1,     2,     3],
           [    4,     5,     6,     7],
           [    8,     9,    10,    11]])
    >>> b
    array([[10000,     1,     2,     3,     4,     5],
           [    6,     7,     8,     9,    10,    11]])
    >>>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57

    12.3 深拷贝

    通过copy函数创建的对象为深拷贝,即对新产生的对象修改值等操作不会影响源矩阵,如下

    >>> import numpy as np
    >>> a=np.arange(12).reshape((3,4))
    >>> a
    array([[ 0,  1,  2,  3],
           [ 4,  5,  6,  7],
           [ 8,  9, 10, 11]])
    >>> b=a.copy()
    >>> b
    array([[ 0,  1,  2,  3],
           [ 4,  5,  6,  7],
           [ 8,  9, 10, 11]])
    >>> b.base is a
    False
    >>> b[0,0]=100
    >>> a
    array([[ 0,  1,  2,  3],
           [ 4,  5,  6,  7],
           [ 8,  9, 10, 11]])
    >>> b
    array([[100,   1,   2,   3],
           [  4,   5,   6,   7],
           [  8,   9,  10,  11]])
    >>>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23

    十三、索引的高级用法

    索引还可以是列表,这样可以一次取出多个数据,如下

    >>> import numpy as np
    >>> arr=np.arange(10,20)
    >>> arr
    array([10, 11, 12, 13, 14, 15, 16, 17, 18, 19])
    >>> index=np.array([1,1,3,7,4])
    >>> index
    array([1, 1, 3, 7, 4])
    >>> arr[index]
    array([11, 11, 13, 17, 14])
    >>> index=np.array([[1,2,3],[4,5,6],[3,4,7]])
    >>> index
    array([[1, 2, 3],
           [4, 5, 6],
           [3, 4, 7]])
    >>> arr[index]
    array([[11, 12, 13],
           [14, 15, 16],
           [13, 14, 17]])
    >>>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    当矩阵为二维数据时,索引的矩阵中元素代表的是每一行,比如如下

    >>> import numpy as np
    >>> arr=np.arange(10,22).reshape((3,4))
    >>> arr
    array([[10, 11, 12, 13],
           [14, 15, 16, 17],
           [18, 19, 20, 21]])
    >>> index=np.array([0,1,0,2])
    >>> arr[index]
    array([[10, 11, 12, 13],
           [14, 15, 16, 17],
           [10, 11, 12, 13],
           [18, 19, 20, 21]])
    >>> index=np.array([[0,1,1,0],[1,2,2,1]])
    >>> index
    array([[0, 1, 1, 0],
           [1, 2, 2, 1]])
    >>> arr[index]
    array([[[10, 11, 12, 13],
            [14, 15, 16, 17],
            [14, 15, 16, 17],
            [10, 11, 12, 13]],
    
           [[14, 15, 16, 17],
            [18, 19, 20, 21],
            [18, 19, 20, 21],
            [14, 15, 16, 17]]])
    >>>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27

    此外,当源矩阵为多维矩阵,可以通过在索引时使用两个索引矩阵来达到取指定位置的一个数,此时此两个索引矩阵需要拥有相同的shape,如下

    >>> import numpy as np
    >>> arr=np.arange(10,22).reshape((3,4))
    >>> arr
    array([[10, 11, 12, 13],
           [14, 15, 16, 17],
           [18, 19, 20, 21]])
    >>> i=np.array([[0,1],[1,2]])
    >>> j=np.array([[2,1],[3,3]])
    >>> i
    array([[0, 1],
           [1, 2]])
    >>> j
    array([[2, 1],
           [3, 3]])
    >>> arr[i,j]
    array([[12, 15],
           [17, 21]])
    >>> arr[i,2]
    array([[12, 16],
           [16, 20]])
    >>> arr[:,j]
    array([[[12, 11],
            [13, 13]],
    
           [[16, 15],
            [17, 17]],
    
           [[20, 19],
            [21, 21]]])
    >>>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30

    可以利用布尔矩阵为矩阵赋值,如下

    >>> import numpy as np
    >>> a=np.arange(12).reshape((3,4))
    >>> a
    array([[ 0,  1,  2,  3],
           [ 4,  5,  6,  7],
           [ 8,  9, 10, 11]])
    >>> b=a>4
    >>> b
    array([[False, False, False, False],
           [False,  True,  True,  True],
           [ True,  True,  True,  True]])
    >>> a[b]
    array([ 5,  6,  7,  8,  9, 10, 11])
    >>> a[b]=0
    >>> a
    array([[0, 1, 2, 3],
           [4, 0, 0, 0],
           [0, 0, 0, 0]])
    >>>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    十四、根据两个数组产生笛卡尔积

    使用np.ix_()可以根据输入两个数组产生笛卡尔积的映射关系,如下,其中np.ix_([0,1,2,3],[0,1,2])会产生(0,0),(0,1),(0,2),(1,0,(1,1,(1,2),(2,0),(2,1),(2,2),然后对矩阵取索引,因此得到期望的结果如下

    >>> import numpy as np
    >>> index=np.ix_([0,1,2,3],[0,1,2])
    >>> index
    (array([[0],
           [1],
           [2],
           [3]]), array([[0, 1, 2]]))
    >>> arr=np.arange(24).reshape((4,6))
    >>> arr[index]
    array([[ 0,  1,  2],
           [ 6,  7,  8],
           [12, 13, 14],
           [18, 19, 20]])
    >>> arr
    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
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
  • 相关阅读:
    Java中的正则表达式
    Go的优雅终止姿势
    为什么个人IP对任何行业都至关重要
    Qt自定义日志输出
    Linux线程的同步与互斥
    搭建vue3源码学习环境
    美发店微信小程序怎么制作
    java培训技术-返回JSON
    【技术美术实践部分】Unity Shader:学习顶点/片元着色器
    违背祖训,微软骚操作强制用户更新至 Win 11 23H2
  • 原文地址:https://blog.csdn.net/redrose2100/article/details/125469008