• numpy如何使用


    numpy介绍

    创建numpy的数组

    一维数组是什么样子

    可以理解为格子纸的一行就是一个一维数据

     two_arr = np.array([1, 2, 3])

    二维数组什么样子

     理解为一张格子纸, 多个一维数组构成一个二维数组

     two_arr = np.array([
         [1, 2, 3],
         [4, 5, 6],
         [7, 8, 9]
     ])
     print(two_arr)
     [[1 2 3]  # 三行三列的二维列表
      [4 5 6]
      [7 8 9]]

    三维数组什么样子

    three_arr = np.array([
        [
            [1, 2, 3],
            [1, 2, 3],
            [1, 2, 3],
            [1, 2, 3],
        ],
        [
            [4, 5, 6],
            [4, 5, 6],
            [4, 5, 6],
            [4, 5, 6],
        ]
    ])
    print(three_arr)
    # [[[1 2 3]
    #   [1 2 3]
    #   [1 2 3]
    #   [1 2 3]]
    # 
    #  [[4 5 6]
    #   [4 5 6]
    #   [4 5 6]
    #   [4 5 6]]]

    np.array()

    传入一个列表, 返回一个数组

    li = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
    arr = np.array(li)
    print(type(arr), arr)
    # <class 'numpy.ndarray'> [0 1 2 3 4 5 6 7 8 9]

    np.arange(10)

    类似于python中的range

    arr = np.arange(10)
    print(type(arr), arr)
    <class 'numpy.ndarray'> [0 1 2 3 4 5 6 7 8 9]
    # 和python的range类型, 顾头不顾尾, 支持步长, 和python的range的区别在于, 起始值和步长支持小数
    arr = np.arange(1.2, 10.5, 0.5)
    print(type(arr), arr)
    # <class 'numpy.ndarray'> [ 1.2  1.7  2.2  2.7  3.2  3.7  4.2  4.7  5.2  5.7  6.2  6.7  7.2  7.7 8.2  8.7  9.2  9.7 10.2]

    拓展: 将一维数据变成多维数组

    前提保证, reshape()中的行和列相乘等于数组中的全部元素的个数

    将一维数组转换成二维数组

    arr = np.arange(0, 15).reshape(3, 5)
    print(arr)
    # [[ 0  1  2  3  4]
    #  [ 5  6  7  8  9]
    #  [10 11 12 13 14]]

    将一维数组转换成三维数组

    arr = np.arange(30).reshape(3, 2, 5)
    print(arr)
    # [[[ 0  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]]]
    
    # 三维数组可以只给出两个数值, 另外一个用-1代替, 自动求剩下一个一个应该是多少
    # 比如:arr = np.arange(30).reshape(3, 2, -1)  会自动求出-1位置的数应该是6

    np.linspace(0, 10, 5)

    把0到10范围的数分成长度为5的数组, 保证每个数之间的差是相等的, 前包后也包

    arr = np.linspace(0, 10, 5)
    print(type(arr), arr)
    # <class 'numpy.ndarray'> [ 0.   2.5  5.   7.5 10. ]

    np.zeros(10)

    创建全0的数组

    arr = np.zeros(10)
    print(arr)
    # [0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]
    # 默认是float类型, 可以指定dtype, 可以指定创建几维的数据传一个元祖, 比如np.zeros(3,2,5), 就是创建一个3页2行5列的全0数组

    np.ones(10)

    创建全1的数组

    arr = np.ones(10)
    print(arr)
    # [1. 1. 1. 1. 1. 1. 1. 1. 1. 1.]
    # 默认使用float类型, 可以指定dtype, 可以指定创建几维的数据传一个元祖, 比如np.ones(3,2,5), 就是创建一个3页2行5列的全1数组

    np.empty(10)

    创建元素为随机的数组

    # np.empty(10)的意义: 向内存要一个长度为10的内存, 并不进行赋值, 内存中原本的数据是什么就是什么, 之后可以对这个里面的值进行覆盖, 效率相对高一点
    arr = np.empty(10)
    print(arr)
    # [1. 1. 1. 1. 1. 1. 1. 1. 1. 1.]

    np.eye(5)

    创建单位矩阵, 方形的, 主对角线为1

    arr = np.eye(5)  # 类似于np.identity(5)
    print(arr)
    # [[1. 0. 0. 0. 0.]
    #  [0. 1. 0. 0. 0.]
    #  [0. 0. 1. 0. 0.]
    #  [0. 0. 0. 1. 0.]
    #  [0. 0. 0. 0. 1.]]

    数组的常用方法

    多维数组的转置

    二维数组: 列转行

    two_arr = np.array([
        [1, 2, 3],
        [4, 5, 6],
        [7, 8, 9],
        [10, 11, 12]
    ])
    ret = two_arr.T
    print(ret)
    # 行: 0  列:1
    # [[ 1  4  7 10]
    #  [ 2  5  8 11]
    #  [ 3  6  9 12]]

    三维数组的转置

    three_arr = np.array([
        [
            [1, 2, 3],
            [4, 5, 6],
            [7, 8, 9],
            [10, 11, 12],
        ],
        [
            [21, 22, 23],
            [24, 25, 26],
            [27, 28, 29],
            [30, 31, 32],
        ]
    ])
    # 页: 0  行:1    列:2
    res = three_arr.transpose(0, 2, 1)
    print(res)
    # [[[ 1  4  7 10]
    #   [ 2  5  8 11]
    #   [ 3  6  9 12]]
    # 
    #  [[21 24 27 30]
    #   [22 25 28 31]
    #   [23 26 29 32]]]

    矩阵的计算

    创建两个矩阵

    a1 = np.array([
        [1, 2, 3],
        [4, 5, 6],
        [7, 8, 9],
    [10, 11, 12]
    ])
    
    a2 = np.array([
    [1, 2, 3],
    [4, 5, 6],
    [7, 8, 9],
    [10, 11, 12]
     ])

    加法

    两个矩阵的结构一致才能进行加法

    a3 = a1 + a2
    print(a3)
    # [[ 2  4  6]
    #  [ 8 10 12]
    #  [14 16 18]
    #  [20 22 24]]

    乘法

    两个矩阵相乘, 结构必须满足以下条件才能相乘
    矩阵一的结构: 3 x 4 矩阵二的结构: 4 x 3
    n(行数) x d(列数) d(行数) x m(列数)
    最后的结果矩阵结构就是n(行) x m(列)
    # 矩阵一的结构
    # [
    #     [1, 2, 3],
    #     [4, 5, 6],
    #     [7, 8, 9],
    #     [10, 11, 12]
    # ]
    
    # 矩阵二的结构
    # [[ 1  4  7 10]
    #  [ 2  5  8 11]
    #  [ 3  6  9 12]]
    
    # 相乘的结果是一个3 x 3的矩阵
    # 计算过程:
    # 矩阵一的第一行和矩阵二的第一列计算,    # 1x1 + 2x2 + 3x3 = 14
    # 矩阵一的第一行和矩阵二的第二列计算,    # 1x4 + 2x5 + 3x6 = 32
    # 矩阵一的第一行和矩阵二的第三列计算,    # 1x7 + 2x8 + 3x9 = 50
    # 矩阵一的第一行和矩阵二的第四列计算,
    # 矩阵一的第二行和矩阵二的第一列计算,
    # 矩阵一的第二行和矩阵二的第二列计算,
    # 矩阵一的第二行和矩阵二的第三列计算,
    # 矩阵一的第二行和矩阵二的第四列计算,
    # 以此类推
    
    print(a1 @ a2.T)  # 矩阵的乘法用 @ 
    # [[ 14  32  50  68]
    #  [ 32  77 122 167]
    #  [ 50 122 194 266]
    #  [ 68 167 266 365]]

    查看一个数组的结构  arr.shape

    一维数组

    one_arr = np.array([1, 2, 3, 4])
    print(one_arr.shape)
    # (4,)

    二维数组

    a2 = np.array([
        [1, 2, 3],
        [4, 5, 6],
        [7, 8, 9],
        [10, 11, 12]
    ])
    print(a2.shape)
    # (4, 3)    (行, 列)

    三维数组

    three_arr = np.array([
        [
            [1, 2, 3],
            [4, 5, 6],
            [7, 8, 9],
            [10, 11, 12],
        ],
        [
            [21, 22, 23],
            [24, 25, 26],
            [27, 28, 29],
            [30, 31, 32],
        ]
    ])
    print(three_arr.shape)
    # (2, 4, 3) (页, 行, 列)

    获取数组中元素的个数  arr.size

    one_arr = np.array([1, 2, 3, 4, 5])
    two_arr = np.array([
        [1, 2, 3, 4],
        [1, 2, 3, 4],
    ])
    three_arr = np.array([
        [
            [1, 2, 3, 4],
            [1, 2, 3, 4],
            [1, 2, 3, 4],
        ],
        [
            [1, 2, 3, 4],
            [1, 2, 3, 4],
            [1, 2, 3, 4],
        ]
    ])
    
    print(one_arr.size)
    print(two_arr.size)
    print(three_arr.size)
    # 5
    # 8
    # 24

    查看数组是几维的  arr.ndim

    one_arr = np.array([1, 2, 3, 4, 5])
    two_arr = np.array([
        [1, 2, 3, 4],
        [1, 2, 3, 4],
    ])
    three_arr = np.array([
        [
            [1, 2, 3, 4],
            [1, 2, 3, 4],
            [1, 2, 3, 4],
        ],
        [
            [1, 2, 3, 4],
            [1, 2, 3, 4],
            [1, 2, 3, 4],
        ]
    ])
    
    print(one_arr.ndim)
    print(two_arr.ndim)
    print(three_arr.ndim)
    # 1
    # 2
    # 3

    查看数组中的数据的数据类型  arr.dtype

    数组中的元素类型是一致

    two_arr = np.array([
        [1, 2, 3, 4],
        [1, 2, 3, 4],
    ])
    
    print(two_arr.dtype)
    # int32 #默认int类型是int32  最大:2147483647   最小: -2147483648

    当数值正好是int32的最大最小的那个数值时, 在对这个属性进行加减, 就会从最大的回退到最小的, 最小的回退到最大的, 这是一个圈

    arr = np.array([0, 2 ** 31 - 1])
    print(arr)
    # [         0 2147483647]   int32最大的数值
    ret = arr + 1
    print(ret)
    # [          1 -2147483648] # 从最大变成了最小

    如何解决这个数值太大无法表示的问题?

    方法一

    定义数组时, 指定大一点的数据类型,指定数据类型为int64, 或更大的object

    arr = np.array([0, 2 ** 31 - 1], dtype="int64")
    ret = arr + 10
    print(ret)
    # [        10 2147483657]

    方法二

    修改已经定义好数据类型的数组, 但是返回新数组, 新数组才是拥有新的数据类型的数组

    arr = np.array([0, 2 ** 31 - 1])
    new_arr = arr.astype("int64")  # 返回一个数据类型是int64的数组
    new_arr = new_arr + 10
    print(new_arr)

    方法三

    使用小数(float), 当要存储的数特别大时, 还可以考虑使用小数(float)的数据类型

    小数的计数法不会出现计算机无法表示的问题

    arr = np.array([0, 2 ** 200], dtype="float")
    ret = arr + 200
    print(ret)
    # [2.00000000e+02 1.60693804e+60]

    注意: 当生成数组时会根据你存储的值的大小动态的使用响应的数据类型, 对数据中的值进行加减时不会在改变, 因为元素的数据类型在存储时已经确定了

    常用的数据类型

    ndarray数据类型:dtype:
    布尔型:bool_
    整型:int    int8    int16   int32   int 64
    无符号整型:uint8   uint16  uint32  uint64  都是正数, 对int要大, 因为没有了负号
    浮点型:float     float16     float32     float64
    复数型:complex   complex64   complex128
    
    

    索引切片

    数组索引切片的特点: python的切片会产生新的数据, 修改新数据不会影响元数据
    但是在数组中却不是这样的, 切片只是在元数据上做标记, 记录3:10这一段数据B可以拿到, 当对B进行修改时
    元数据也会跟着变化, 这样做的目的就是节省时间和空间, 当数据较大时, 对数据进行切片比较快
    对切片后的数据使用copy()可以进行拷贝, 修改数据不会再影响元数据
    one_arr[0:5].copy()

    普通索引

    一维数组普通索引

    one_arr = np.arange(10)
    print(one_arr)
    # [0 1 2 3 4 5 6 7 8 9]
    # 取前5个
    print(one_arr[0:5])
    # [0 1 2 3 4]

    二维数组普通索引

    two_arr = np.arange(15).reshape(3, 5)
    print(two_arr)
    # [[ 0  1  2  3  4]
    #  [ 5  6  7  8  9]
    #  [10 11 12 13 14]]

    1. 取到第二行第三列的那个数

    print(two_arr[2, 3])
    # 13

    2. 取第一行

    print(two_arr[0,])
    # two_arr[行: 列]
    # [0 1 2 3 4]

    3. 取第一列

    print(two_arr[0:,0])    # 所有的行0:    第一列0

    4. 从中间去一个长方形

    print(two_arr[0:2, 1:4])    # 切片是前包后不包的
    # [[1 2 3]
    #  [6 7 8]]

    布尔型索引

    1. 问题: 给出一个数组, 选出数组中所有大于5的数
    python列表的做法

    li = [random.randint(1, 10) for n in range(10)]
    # python列表的做法
    # res = list(filter(lambda x: x > 5, li))
    # print(res)


    数组的做法

    arr = np.array(li)
    print(arr[arr > 5])
    
    # 为什么这样写?
    # 先看看arr > 5的结果是什么
    print(arr > 5)
    # [ True  True  True  True False False  True  True  True  True]
    # 返回一个全是布尔的数组
    # 将5和原数组中的值进行比较返回布尔值
    # 返回使用这些布尔值进行取值, 将对应位置上是True的值取出了
    # arr[ True  True  True  True False False  True  True  True  True]
    # 这样就把结果取出来了

    2. 问题: 给出一个数组, 选出所有大于5, 并且是偶数的数

    print(arr[(arr > 5) & (arr % 2 == 0)])
    # 两个条件, 当两个条件都是True时才是True
    # 两个条件先分别计算, 得出两个全是布尔值的数组, 然后两个数组进行 & 计算, 在使用得出的结果取原数组中取值
    # 注意 and    和   & 的区别
    # and: 是python的关键字
    # &: 是运算符
    # 在这里要使用运算符

    3. 问题: 给出一个数组, 选出所有除了大于5以外的数

    print(arr[~(arr > 5)])
    # 找出大于5的, 然后使用 ~ 取反

    4. 问题: 给出一个数组, 计算该数组中大于5的数字占的比重

    print((arr[arr > 5]).size / arr.size)
    # 计算出大于5的数量, 然后除以全部的数量

    花式索引

    给出一个数据取出索引为奇数的数值

    一维数组

    arr = np.arange(10)
    print(arr[[1, 3, 5, 7, 9]])
    # 索引取值使用一个列表, 会取值和该列表值对应的索引位置的值, 保证列表中的元素都能作为索引, 不大于大最大索引
    # [1 3 5 7 9]

    二维数组

    # 使用花式索引是, 行列不能同时使用花式索引, 例如print(arr[[1, 2], [0, 1]])
    arr = np.arange(15).reshape(3, 5)
    print(arr)
    # [[ 0  1  2  3  4]
    #  [ 5  6  7  8  9]
    #  [10 11 12 13 14]]
    # print(arr[[1, 2], :][:, [0, 1]])
    # [[ 5  6]
    #  [10 11]]

    通用函数

    np.abs(arr) 绝对值

    arr = np.arange(-5, 10).reshape(3, 5)
    print(arr)
    # [[-5 -4 -3 -2 -1]
    #  [ 0  1  2  3  4]
    #  [ 5  6  7  8  9]]
    print(np.abs(arr))
    # [[5 4 3 2 1]
    #  [0 1 2 3 4]
    #  [5 6 7 8 9]]

    np.sqrt(arr) 开根号

    arr = np.arange(1, 16).reshape(3, 5)
    print(np.sqrt(arr))
    # [[1.         1.41421356 1.73205081 2.         2.23606798]
    #  [2.44948974 2.64575131 2.82842712 3.         3.16227766]
    #  [3.31662479 3.46410162 3.60555128 3.74165739 3.87298335]]

    np.exp() 指数

    arr = np.arange(1, 16).reshape(3, 5)
    print(np.exp(arr))
    # [[2.71828183e+00 7.38905610e+00 2.00855369e+01 5.45981500e+01
    #   1.48413159e+02]
    #  [4.03428793e+02 1.09663316e+03 2.98095799e+03 8.10308393e+03
    #   2.20264658e+04]
    #  [5.98741417e+04 1.62754791e+05 4.42413392e+05 1.20260428e+06
    #   3.26901737e+06]]

    取整

    arr = np.array([3.4, 3.3, 4.6, 5.0])
    print(np.ceil(arr))  # 向上取整  4.5取5
    print(np.floor(arr))  # 向下取整  4.5取4
    print(np.trunc(arr))  # 向0取整
    print(np.rint(arr))  # 四舍五入取整

    np.array() 将数组变成整数部分和小数部分两个数组

    将数据分成两个数组, 一个是整数部分, 一个是小数部分, 都会带着各自的符号

    arr = np.array([-3.4, 3.3, -4.6, 5.0])
    print(np.modf(arr)) 
    # (array([-0.4,  0.3, -0.6,  0. ]), array([-3.,  3., -4.,  5.]))

    isnan (not a number)

    **各种没有确定值的数据运算会返回nan, 比如对-1开根号
    nan不等于任何数, 自己都不等于自己

    a = float("nan")
    print(a == a)
    # False
    print(type(a), a)
    # <class 'float'> nan

    为什么会有nan?

    nan常用作表示数据缺失值, 有这个值, 但是暂时不知道的值叫缺失值
    因为在array进行计算时, 加入要计算一亿个数, 但是其中有一个数是没有结果的, 正常情况下会报错
    那么这次计算就白做了, 但是numpy的array为了让这次计算有效, 就使用了nan

    那些情况会产生nan?

    arr = np.array([0, 1, 2, 3])
    print(arr / arr)
    # [nan  1.  1.  1.]
    # 因为0/0没有结果, 就用nan代替了

    判断一个数组中是否有nan

    arr = np.array([0, 1, 2, 3])
    res = arr / arr
    print(np.isnan(res))
    # [ True False False False]
    # 数组中的第一个元素就是nan

    如何将排除数据中的nan?

    print(arr[~np.isnan(res)])  # 通过布尔值索引
    # [1 2 3]

    如何将数组中的nan改为0?

    arr[np.isnan(res)] = 0  # 所有为True的位置写一个0
    print(arr)

    如何创建一个nan?

    print(np.nan)
    # nan
    print(np.NAN)
    # nan

    np.isinf()  无穷大, 无穷小

    inf: 无穷大, -inf: 无穷小
    自己等于自己

    常用的数学统计方法

    常用函数

    arr = np.arange(10)
    print(arr.sum())  # 求和
    print(arr.mean())  # 求平局值
    print(arr.max())  # 最大值
    print(arr.min())  # 最小值
    print(arr.var())  # 求方差   [1,2,3,4,5]  平均值:3, ((1-3**2) + (2-3**2) + (3-3**2) + (4-3**2) + (5-3**2)) / 5(长度)
    print(arr.std())  # 标准差   等于方差开根号
    print(arr.cumsum())  # 前缀和
    print(arr.argmin())  # 返回最小数的索引值
    print(arr.argmax())  # 返回最大数的索引值

    应用示例

    1. 估算数组内数值的范围?

    arr = np.array([random.uniform(10, 20) for n in range(100)])
    print(arr.mean() - 2 * arr.std())  # 平均值 - 标准差
    # 9.024533852997003
    print(arr.mean() + 2 * arr.std())  # 平均值 + 标准差
    # 20.533572296358937

    2. 求某一区间的所有数值的和

    arr = np.array([1, 2, 3, 7, 6, 5, 10])
    a = arr.cumsum()
    print(a)
    # [ 0  1  3  6 10 15 21 28 36 45]
    # 求索引4到索引8之间的所有数值的和 6+5=11
    res = a[5] - a[3]  # 顾尾不顾头
    print(res)
    # 11

    随机数

    和python的random用法基本一致, 区别在于可以直接将随机数生成到指定形状的数组中

    np.random.random()

    print(np.random.random())  # 生产0到1之间的小数
    # 还可以生成到数组中
    # 生成一维数组
    print(np.random.random(10))
    # [0.75789864 0.49982257 0.32940952 0.57216004 0.17562665 0.50703461
    #  0.36919792 0.20893032 0.09530242 0.66015132]
    
    # 生成二维数组
    print(np.random.random((3, 5)))
    # [[0.47324357 0.73385845 0.89099074 0.50889891 0.21902953]
    #  [0.8889513  0.48389661 0.72072126 0.36994093 0.97653365]
    #  [0.38499637 0.82375443 0.52682468 0.7266469  0.19659174]]

    其他

    print(np.random.randint(10, 20, (3, 5)))  # 生成随机整数
    print(np.random.uniform(10, 20, (3, 5)))  # 生成随机小数, 每个数出现的次数大概相同
    print(np.random.normal(6, 10))  # 随机小数, 有负数, 正态分布, 中间的数出现的几率大
    print(np.random.choice([1, 2, 3, 4, ], 2))  # 给定的形状中随机选择, 可以指定个数
    
    arr = np.arange(10).reshape(2, 5)
    np.random.shuffle(arr)  # 打乱给定形状中的数据, 打乱的是元数据
    print(arr)


  • 相关阅读:
    [转]开源游戏AI引擎列表与游戏中的人工智能
    [转]刨根问底!曲面细分技术到底是个啥?
    [转]link time code generation
    [转]PythonQt
    [转]Free Game Development Libraries
    Java虚拟机(二):垃圾回收算法 时间
    Java虚拟机(一):JVM的运行机制 时间
    Java虚拟机(四):常用JVM配置参数 时间
    Java虚拟机(三):垃圾收集器 时间
    mov offset和lea的区别
  • 原文地址:https://www.cnblogs.com/594504110python/p/10229230.html
Copyright © 2020-2023  润新知