zoukankan      html  css  js  c++  java
  • 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)


  • 相关阅读:
    布局重用 include merge ViewStub
    AS 常用插件 MD
    AS 2.0新功能 Instant Run
    AS .ignore插件 忽略文件
    AS Gradle构建工具与Android plugin插件【大全】
    如何开通www国际域名个人网站
    倒计时实现方案总结 Timer Handler
    AS 进行单元测试
    RxJava 设计理念 观察者模式 Observable lambdas MD
    retrofit okhttp RxJava bk Gson Lambda 综合示例【配置】
  • 原文地址:https://www.cnblogs.com/xiao-xue-di/p/10257329.html
Copyright © 2011-2022 走看看