当前位置 博文首页 > 不太冷的莱昂的博客:Python中的Numpy

    不太冷的莱昂的博客:Python中的Numpy

    作者:[db:作者] 时间:2021-09-02 16:34

    为什么要用numpy

    ??? Python中提供了list容器,可以当作数组使用。但列表中的元素可以是任何对象,因此列表中保存的是对象的指针,这样一来,为了保存一个简单的列表[1,2,3]。就需要三个指针和三个整数对象。对于数值运算来说,这种结构显然不够高效。
    ??? Python虽然也提供了array模块,但其只支持一维数组,不支持多维数组(在TensorFlow里面偏向于矩阵理解),也没有各种运算函数。因而不适合数值运算。
    ??? NumPy的出现弥补了这些不足。

    (——摘自张若愚的《Python科学计算》)

    import numpy as np

    ?

    数组创建

    ## 常规创建方法
    a = np.array([2,3,4])
    b = np.array([2.0,3.0,4.0])
    c = np.array([[1.0,2.0],[3.0,4.0]])
    d = np.array([[1,2],[3,4]],dtype=complex) # 指定数据类型
    print a, a.dtype
    print b, b.dtype
    print c, c.dtype
    print d, d.dtype

    ?

    [2 3 4] int32
    [ 2.? 3.? 4.] float64
    [[ 1.? 2.]
    ?[ 3.? 4.]] float64
    [[ 1.+0.j? 2.+0.j]
    ?[ 3.+0.j? 4.+0.j]] complex128

    ?

    数组的常用函数
    print np.arange(0,7,1,dtype=np.int16) # 0为起点,间隔为1时可缺省(引起歧义下不可缺省)
    print np.ones((2,3,4),dtype=np.int16) # 2页,3行,4列,全1,指定数据类型
    print np.zeros((2,3,4)) # 2页,3行,4列,全0
    print np.empty((2,3)) #值取决于内存
    print np.arange(0,10,2) # 起点为0,不超过10,步长为2
    print np.linspace(-1,2,5) # 起点为-1,终点为2,取5个点
    print np.random.randint(0,3,(2,3)) # 大于等于0,小于3,2行3列的随机整数

    ?

    [0 1 2 3 4 5 6]
    [[[1 1 1 1]
    ? [1 1 1 1]
    ? [1 1 1 1]]

    ?[[1 1 1 1]
    ? [1 1 1 1]
    ? [1 1 1 1]]]
    [[[ 0.? 0.? 0.? 0.]
    ? [ 0.? 0.? 0.? 0.]
    ? [ 0.? 0.? 0.? 0.]]

    ?[[ 0.? 0.? 0.? 0.]
    ? [ 0.? 0.? 0.? 0.]
    ? [ 0.? 0.? 0.? 0.]]]
    [[? 1.39069238e-309?? 1.39069238e-309?? 1.39069238e-309]
    ?[? 1.39069238e-309?? 1.39069238e-309?? 1.39069238e-309]]
    [0 2 4 6 8]
    [-1.?? -0.25? 0.5?? 1.25? 2.? ]
    [[1 0 1]
    ?[0 1 0]]

    ?

    ?类型转换
    print float(1)
    print int(1.0)
    print bool(2)
    print float(True)

    ??

    1.0
    1
    True
    1.0

    ??

    数组输出

    ????从左到右,从上向下
    ??? 一维数组打印成行,二维数组打印成矩阵,三维数组打印成矩阵列表

    print np.arange(1,6,2)
    print np.arange(12).reshape(3,4) # 可以改变输出形状
    print np.arange(24).reshape(2,3,4)# 2页,3行,4页

    ??

    [1 3 5]
    [[ 0? 1? 2? 3]
    ?[ 4? 5? 6? 7]
    ?[ 8? 9 10 11]]
    [[[ 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 = np.array([1,2,3,4])
    b = np.arange(4)
    print a, b
    print a-b
    print a*b
    print a**2
    print 2*np.sin(a)
    print a>2
    print np.exp(a) # 指数

    ???

    [1 2 3 4] [0 1 2 3]
    [1 1 1 1]
    [ 0? 2? 6 12]
    [ 1? 4? 9 16]
    [ 1.68294197? 1.81859485? 0.28224002 -1.51360499]
    [False False? True? True]
    [? 2.71828183?? 7.3890561?? 20.08553692? 54.59815003]

    ?

    ## 矩阵运算(二维数组)
    a = np.array([[1,2],[3,4]]) # 2行2列
    b = np.arange(6).reshape((2,-1)) # 2行3列
    print a,b
    print a.dot(b) # 2行3列

    ?

    [[1 2]
    ?[3 4]] [[0 1 2]
    ?[3 4 5]]
    [[ 6? 9 12]
    ?[12 19 26]]

    ?

    ## 非数组运算,调用方法
    a = np.random.randint(0,5,(2,3))
    print a
    print a.sum(),a.sum(axis=1),a.sum(0) # axis用于指定运算轴(默认全部,可指定0或1)
    print a.min(),a.max(axis=1),a.mean(axis=1) # axis = 0: 按列计算,axis = 1: 按行计算
    print a.cumsum(1) # 按行计算累积和

    ?

    [[2 3 3]
    ?[0 2 1]]
    11 [8 3] [2 5 4]
    0 [3 2] [ 2.66666667? 1.??????? ]
    [[2 5 8]
    ?[0 2 3]]

    ?

    索引,切片,迭代

    ## 一维数组
    a = np.arange(0,10,1)**2
    print a
    print a[0],a[2],a[-1],a[-2] # 索引从0开始,-1表示最后一个索引
    print a[2:5],a[-5:-1] # 包括起点,不包括终点
    a[-1] = 100; print a # 赋值
    a[1:4]=100; print a # 批量赋值
    a[:6:2] = -100; print a # 从开始到第6个索引,每隔一个元素(步长=2)赋值
    print a[: :-1];print a # 将a逆序输出,a本身未发生改变
    b = [np.sqrt(np.abs(i)) for i in a]; print b # 通过遍历赋值

    ??

    [ 0? 1? 4? 9 16 25 36 49 64 81]
    0 4 81 64
    [ 4? 9 16] [25 36 49 64]
    [? 0?? 1?? 4?? 9? 16? 25? 36? 49? 64 100]
    [? 0 100 100 100? 16? 25? 36? 49? 64 100]
    [-100? 100 -100? 100 -100?? 25?? 36?? 49?? 64? 100]
    [ 100?? 64?? 49?? 36?? 25 -100? 100 -100? 100 -100]
    [-100? 100 -100? 100 -100?? 25?? 36?? 49?? 64? 100]
    [10.0, 10.0, 10.0, 10.0, 10.0, 5.0, 6.0, 7.0, 8.0, 10.0]

    ??

    ## 多维数组
    a = np.arange(0,20).reshape((4,5))
    print a, a[2,3], a[:,1], a[1:4,2], a[1:3,:]
    print a[-1] # 相当于a[-1,:],即索引少于轴数时,确实的索引默认为整个切片

    b = np.arange(0,24).reshape((2,3,4))
    print b,b[1] # 相当于b[1,:,:] 和b[1,...]
    print '-------------------'
    for row in a:
    ??? print row # 遍历以第一个轴为基础

    ?

    [[ 0? 1? 2? 3? 4]
    ?[ 5? 6? 7? 8? 9]
    ?[10 11 12 13 14]
    ?[15 16 17 18 19]] 13 [ 1? 6 11 16] [ 7 12 17] [[ 5? 6? 7? 8? 9]
    ?[10 11 12 13 14]]
    [15 16 17 18 19]
    [[[ 0? 1? 2? 3]
    ? [ 4? 5? 6? 7]
    ? [ 8? 9 10 11]]

    ?[[12 13 14 15]
    ? [16 17 18 19]
    ? [20 21 22 23]]]

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

    ??

    形状操作

    a = np.floor(10*np.random.random((3,4)))
    print a, a.shape #输出a的形状
    print a.ravel() # 输出平坦化后的a(a本身不改变)
    a.shape = (6,2); print a # 改变a的形状
    print a.transpose() # 输出a的转置

    ?

    [[ 0.? 4.? 3.? 2.]
    ?[ 1.? 1.? 3.? 3.]
    ?[ 4.? 4.? 6.? 5.]] (3, 4)
    [ 0.? 4.? 3.? 2.? 1.? 1.? 3.? 3.? 4.? 4.? 6.? 5.]
    [[ 0.? 4.]
    ?[ 3.? 2.]
    ?[ 1.? 1.]
    ?[ 3.? 3.]
    ?[ 4.? 4.]
    ?[ 6.? 5.]]
    [[ 0.? 3.? 1.? 3.? 4.? 6.]
    ?[ 4.? 2.? 1.? 3.? 4.? 5.]]

    ?

    ##?补充:reshape和resize
    a = np.array([[1,2,3],[4,5,6]])
    b = a
    a.reshape((3,2))# 不改变数组本身的形状
    print a
    b.resize((3,2))# 改变数组本身形状
    print b

    ??

    [[1 2 3]
    ?[4 5 6]]
    [[1 2]
    ?[3 4]
    ?[5 6]]

    ---------------------

    ? 在numpy模块中,我们经常会使用resize 和 reshape,在具体使用中,通常是使用resize改变数组的尺寸大小,使用reshape用来增加数组的维度。

    1.resize

    之前看到别人的博客说,resize没有返回值,其实这取决于你如何使用resize,resize有两种使用方式,一种是没有返回值的,直接对原始的数据进行修改,还有一种用法是有返回值的,所以不会修改原有的数组值。

    1.1有返回值,不对原始数据进行修改

    ??? import numpy as np
    ??? X=np.array([[1,2,3,4],
    ????????????????? [5,6,7,8],
    ????????????????? [9,10,11,12]])
    ??? ?
    ??? X_new=np.resize(X,(3,3)) # do not change the original X
    ??? print("X:\n",X)? #original X
    ??? print("X_new:\n",X_new) # new X
    ??? ?
    ??? >>
    ??? X:
    ???? [[ 1? 2? 3? 4]
    ???? [ 5? 6? 7? 8]
    ???? [ 9 10 11 12]]
    ??? X_new:
    ???? [[1 2 3]
    ???? [4 5 6]
    ???? [7 8 9]]

    1.2?无返回值,直接修改原始数组的大小

    ??? import numpy as np
    ??? X=np.array([[1,2,3,4],
    ????????????????? [5,6,7,8],
    ????????????????? [9,10,11,12]])
    ??? ?
    ??? X_2=X.resize((3,3))??#change the original X ,and do not return a value
    ??? print("X:\n",X)? # change the original X
    ??? print("X_2:\n",X_2) # return None
    ??? ?

    ??? ?
    ??? X:
    ???? [[1 2 3]
    ???? [4 5 6]
    ???? [7 8 9]]
    ??? X_2:
    ???? None


    2.reshape

    给数组一个新的形状而不改变其数据

    ??? import numpy as np
    ??? X=np.array([1,2,3,4,5,6,7,8])
    ??? ?
    ??? X_2=X.reshape((2,4)) #retuen a 2*4 2-dim array
    ??? X_3=X.reshape((2,2,2)) # retuen a 2*2*2 3-dim array
    ??? ?
    ??? print("X:\n",X)
    ??? print("X_2:\n",X_2)
    ??? print("X_3:\n",X_3)
    ??? ?
    ??? >>
    ??? X:
    ???? [1 2 3 4 5 6 7 8]
    ??? X_2:
    ???? [[1 2 3 4]
    ???? [5 6 7 8]]
    ??? X_3:
    ???? [[[1 2]
    ????? [3 4]]
    ??? ?
    ???? [[5 6]
    ????? [7 8]]]

    cs