笔记:numpy

2021-06-01  本文已影响0人  茂财

NumPy 和它的 ndarray 对象,这个对象为 Python 多维数组提供了高效的存储和处理方法

  1. 数组基础

    1. 向量 (一维数组)、矩阵 (二维数组)
    2. 创建数组
    • 从Python列表创建

      np.array(range(10),dtype='float32')
      np.array([range(i,i+3)for i in range(2,7,2)])
      
    • 用numpy内置方法创建

      np.zeros((3,5))            #3*5的数值都是0的二维浮点数组
      np.ones((3,5),dtype='int')   #3*5 数值都是1的二维整数数组
      np.full((3,5),'python')      #3*5 数值都是'python'的二维数组
      np.arange(20,0,-5)           #返回一个线性序列,与range()类似,arange函数对数据类型敏感,如果将整数作为参数,生成整数数组;如果输入浮点数(例如arange(3.)),则生成浮点数组
      np.arange(3.0)
      >>> array([ 0., 1., 2.])
      np.linsapce(1,10,5)            #返回长度为5的数组,数值线性均匀分布在1~10之间的浮点数,不受舍入错误的影响
      np.random.random((3,5))        #返回3*5 二维数组,随机分布在0~1之间的浮点数
      np.random.randint(0,10,(3,5))#创建3*5二维整数数组,随机分布在[0,10)之间的整数
      np.random.normal(0,1,(3,5)) #创建3*5二维浮点数组,平均值为0,方差(每个数与平均数的差的平均数)为1
      np.eye(5)                 #创建5*5单位矩阵,对角线为1的方阵
      np.eye(5,3,k=1,dtype=int)  #5行3列,值是1的对角线从第2列开始
      array([[0, 1, 0],
             [0, 0, 1],
             [0, 0, 0],
             [0, 0, 0],
             [0, 0, 0]])
      np.empty(3)                   #长度为3,数值是内存随机数   numpy的数据类型
      
  2. numpy的数据类型

    • 指定数据类型 dtype = 'float32'
    • 或相关np对象 dtype = np.int32
  3. numpy的数据类型

    • 指定数据类型 dtype = 'float32'
    • 或相关np对象 dtype = np.int32
  4. 数组的操作

    • 数组的属性

      na=np.randdom.randint(1,10,size=(3,5))
      na.ndim        # 2 数组的维度
      na.shape   #(3,5) 数组每个维度的大小
      na.size        # 15 数组的总大小
      na.dtype   #dtype('int32') 数组的数据类型
      na.nbytes  #60 数组总的字节数
      na.itmesize # 4 每个元素的字节数
      
      #设置一组种子,保证随机数相同
      np.random.seed(1)
      x1=np.random.randint(10,size=10)   #[5 8 9 5 0 0 1 7 6 9]
      np.random.seed(1)
      x2=np.random.randint(10,size=10)   #[5 8 9 5 0 0 1 7 6 9]
      np.random.seed(1)
      x3=np.random.randint(10,size=10)   #[5 8 9 5 0 0 1 7 6 9]
      
      # randint(low,high=none,size=none);省略high 则返回[0,low)的区域随机数
      
    • 数组的索引

      数组的索引与列表相似,可以通过索引查询或修改,不过数组的类型是固定的,会被自动修改
      na=np.array([[1,2],[3,4],[5,6]])
      na[2][0]=50
      
        • 数组的切片
      • 关于数组切片有一点很重要也非常有用,那就是数组切片返回的是数组数据的视图,而不是数值数据的副本,如果修改这个子数组,原始数组也被修改!!!!
      • arr [ 行范围:列范围 ] 行范围:垂直方向 axis=0;列范围:水平方向axis=1
      • Snipaste_2021-05-27_15-22-25.png
      na[:,1] #获取第二列 array([2, 4, 6])
      na[1,:] #获取第二行 array([3, 4])</pre>
      
      • 创建数组的副本
x=na.cpoy()
Snipaste_2021-05-28_10-57-41.png
      • na=np.array([[ 1, 2, 3], [4, 5, 6],[ 7, 8, 9]])
         # 默认沿着第一个轴 (x轴折叠)拼接
        n1=np.concatenate([na,na,na])
        # # 沿着第二个轴(y轴折叠)拼接
        n1=np.concatenate([na,na,na],axis=1)
        
      • 固定维度,使用vstack(垂直栈)与hstack(水平栈) 进行拼接,np.dstack 将沿着第三个维度.
        • na=array([[1, 2, 3],[4, 5, 6],[7, 8, 9]])
          n1=np.array([9,9,9])
          np.vstack([n1,na])  
          '''array([[9, 9, 9],
                 [1, 2, 3],
                 [4, 5, 6],
                 [7, 8, 9]])
          '''
          n1=np.array([[9],[9],[9]])
          np.hstack([na,n1])
          '''
          array([[1, 2, 3, 9],
                 [4, 5, 6, 9],
                 [7, 8, 9, 9]])
          '''
          
        • 切割

          • 分裂可以通过 np.split()、np.hsplit()和 np.vsplit() 函数来实现。可以向函数传递一个索引列表作为参数,索引列表记录的是分裂点位置。值得注意的是,N 分裂点会得到 N + 1 个子数组。相关的np.hsplit 和 np.vsplit 的用法也类似.
            • na=array([1, 2, 3, 4, 5, 6, 7, 8, 9])
              np.split(na,(3,5))  #[array([1, 2, 3]), array([4, 5]), array([6, 7, 8, 9])]
              na=np.arange(16).reshape(4,4)
              np.vsplit(na,[2])
              '''
              [array([[0, 1, 2, 3],
                     [4, 5, 6, 7]]), array([[ 8,  9, 10, 11],
                     [12, 13, 14, 15]])]
              '''
              np.hsplit(na,[3])
              '''
              [array([[ 0,  1,  2],
                     [ 4,  5,  6],
                     [ 8,  9, 10],
                     [12, 13, 14]]), array([[ 3],
                     [ 7],
                     [11],
                     [15]])]
              
        • 数组的增删操作

          • 增加 :np.append(array,data])

          • 插入:np.insert(arr, obj, values, axis) #obj插入元素位置

            a = np.array([[1,2],[3,4],[5,6]])
            b=np.insert(a,1,11,axis = 1)  #增加列上得元素
            
            # 输出
            array([[ 1, 11,  2],
                   [ 3, 11,  4],
                   [ 5, 11,  6]])
            
            a = np.array([[1,2],[3,4],[5,6]])
            b=np.insert(a,1,[2,6],axis = 0) #增加行上得元素
            
            # 输出
            array([[1, 2],
                   [2, 6],
                   [3, 4],
                   [5, 6]])
            
        • numpy.delete(arr, obj, axis) 在副本上操作,返回删除了某些元素的新数组


数组的计算:通用函数
通用函数有两种存在形式:一元通用函数(unary ufunc)对单个输入操作,二元通用函数(binary ufunc)对两个输入操作
  1. 数组的加减乘除运算
    运算符  对应的通用函数 描述
    +    np.add  加法运算(即 1 + 1 = 2)
    -    np.subtract 减法运算(即 3 - 2 = 1)
    -    np.negative 负数运算( 即 -2)
    *    np.multiply 乘法运算(即 2 * 3 = 6)
    /    np.divide   除法运算(即 3 / 2 = 1.5)
    //   np.floor_divide 地板除法运算(floor division,即 3 // 2 = 1)
    **   np.power    指数运算(即 2 ** 3 = 8)
    %    np.mod  模 / 余数( 即 9 % 4 = 1)
    
    na=np.arange(5)
    print(na+2)
    print(np.add(na,2))
    
  2. 绝对值 abs()或 absolute()
    na=np.arange(-5,0)
    print(na)
    print(np.abs(na))
    
    
  3. 三角函数
    np.pi
    np.sin(theta)    /np.arsin(theta)
    np.cos(theta)   /np.arcos(theta)
    np.tan(theta)    /np.artan(theta)
    
  4. 指数与对数

    #指数
    e^x  --->np.exp(x)
    2^x  --->np.exp2(x)
    3^x  --->np.power(3,x)
    #对数
    ln(x) --->np.log(x)
    log2(x) --->np.log2(x)
    log10(x) --->np.log10(x)
    
  5. 通用函数特性:

    1. 指定输出位置:所有的通用函数都可以通过 out 参数来指定计算结果的存放位置
      y=np.empty(5)
      np.multiply(3,na,out=y)
      y  输出 array([15., 12.,  9.,  6.,  3.])
      
    2. 聚合功能:例如用任何通用函数的 reduce 方法(函数也有自己的方法)
       na=array([5, 4, 3, 2, 1])
      np.add.reduce(na)
      >>>15
      
    3. 外积 :任何通用函数都可以用 outer 方法获得两个不同输入数组所有元素对的函数运算结果
      na=array([5, 4, 3, 2, 1])
      np.add.outer(na,na)
      >>> array([[10,  9,  8,  7,  6],
             [ 9,  8,  7,  6,  5],
             [ 8,  7,  6,  5,  4],
             [ 7,  6,  5,  4,  3],
             [ 6,  5,  4,  3,  2]])
      
      axis 关键字指定的是数组将会被折叠的维度,而不是将要返回的维度。因此指定axis=0 意味着沿着第一个轴(x轴)折叠——对于二维数组,这意味着每一列的值都将被聚合.
    4. 其他聚合
Snipaste_2021-05-26_08-39-26.png

数组的计算:广播

什么是数组的广播?

数组的广播,可以理解为数组扩展,为了不同维度的数组之间的运算,将它们扩展或广播使其能够变形成同维度数组从而进行运算。参考可视化展示

Snipaste_2021-05-26_09-18-36.png
a=np.arange(3)
b=a.reshape(3,1)
a+b
array([[0, 1, 2],[1, 2, 3],[2, 3, 4]])

广播规则:


数组的运算:比较、掩码、布尔逻辑

  1. 比较运算:与通用函数相似,数组的比较运算返回相应布尔值数组
Snipaste_2021-05-26_10-39-40.png
  1. na=np.arange(10)
    na>3
    array([False, False, False, False, False, False,  True,  True,  True,True])
    
  1. 操作布尔数组
    #统计记录个数
    na=np.arange(1,10).reshape(3,3)
    np.count_nonzero(na>6)  # 3 返回为TRUE的个数
    np.sum(na>6)  # 3 同理
    np.sum(na>5,axis=1) #  array([0, 1, 3])    沿着列返回个数组
    
    #类似的函数还有 any()/all(na>6,axis=1)
    
  2. 布尔运算(逻辑运算或逐位运算)
    运算符  对应通用函数
    &    np.bitwise_and
    |    np.bitwise_or
    ^    np.bitwise_xor
    ~    np.bitwise_not
    
    np.sum(na>5,axis=1)&na<3
    array([[ True,  True, False],
           [ True,  True,  True],
           [ True,  True,  True]])
    
  3. 将布尔数组作为掩码
    使用布尔数组作为掩码,通过该掩码获得数据的子数据集,换句话说,所有的这些值是掩码数组对应位置为 True 的值。
    n1=np.arange(1,9).reshape((4,2))
    n1>5
    array([[False, False],
           [False, False],
           [False,  True],
           [ True,  True]])
           
    n1[n1>5]
    array([6, 7, 8])       
    
    通过将布尔操作、掩码操作和聚合结合,可以快速回答对数据集提出的这类问题
  4. 关键字 and 和 or,以及逻辑操作运算符 & 和 | 的区别是什么,什么时候该选择哪一种?
    • 当你使用 and 或 or 时,就等于将这个对象当作整个布尔实体。在 Python 中,所有非零的整数都会被当作是 True:
      >>> bool(42),bool(59)
      (True, True)
      >>> 42 and 0
      0
      >>> 42 or 0
      42
      >>> bool(42 and 0)
      False
      >>> bool(42 or 0)
      True
      
    • 当你对整数使用 & 和 | 时,表达式操作的是元素的比特,将 and或 or 应用于组成该数字的每个比特, & 和 | 运算时,对应的二进制比特位进行比较以得到最终结果
      >>> bin(42),bin(59)
      ('0b101010', '0b111011')
      >>> bin(42 &59)
      '0b101010'
      >>> bin(42 | 59)
      '0b111011'
      >>> 59&42
      42
      >>> 42 |59
      59
      
    • 当 NumPy 中有一个布尔数组时,该数组可以被当作是由比特字符组成的,其中 1 = True、0 = False。这样的数组可以用上

      面介绍的方式进行 & 和 | 的操作;而用 or 来计算这两个数组时,Python 会计算整个数组对象的真或假,这会导致程序出错;同样,对给定数组进行逻辑运算时,你也应该使用 | 或 &,而不是or 或 and

       A = np.array([1, 0, 1, 0, 1, 0], dtype=bool)
      B = np.array([1, 1, 1, 0, 1, 1], dtype=bool)
      A | B
      Out[37]: array([ True, True, True, False, True, True], dtype=bool)
          
       x = np.arange(10)
      (x > 4) & (x < 8)
      Out[39]: array([False, False, ..., True, True, False, False], dtype=bool)    
      

花哨的索引

花哨的索引和前面那些简单的索引非常类似,但是传递的是索引数组,而不是单个标量。花哨的索引让我们能够快速获得并修改复杂的数组值的子数据集。
  1. 传递一个索引数组来一次性获得多个数组元素
    n1=np.arange(12)
    >>> n1
    array([ 0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11])
    >>> ind=[0,5,7]
    >>> n1[ind]
    array([0, 5, 7])
    
  2. 结果的形状与索引数组的形状一致,而不是与被索引数组的形状一致
    ind=np.array([[3,4,5],[7,8,9]])
    >>> n1[ind]
    array([[3, 4, 5],[7, 8, 9]])
    
  3. 多维度
    n1=np.arange(12).reshape(3,4)
     row=np.array([0,1,2])
     col=np.array([1,3,3])
     n1[row,col]
    array([ 1,  7, 11])   #n1[0,1]=1;n1[1,3]=7;n1[2,3]=11
    
  4. 组合索引
    • 将花哨的索引和简单的索引组合使用
    • 将花哨的索引和切片组合使用
    • 将花哨的索引和掩码组合使用
    • 索引选项的组合可以实现非常灵活的获取和修改数组元素的操作
    • 花哨的索引可以被用于获取部分数组,它也可以被用于修改部分数组。

数组的排序


数组的结构化:numPy 的结构化数组和记录数组,它们为复合的、异构的数据提供了非常有效的存储,其实pandas更实用
data = np.zeros(4, dtype={'names':('name', 'age', 'weight'),'formats':('U10', 'i4', 'f8')})
上一篇下一篇

猜你喜欢

热点阅读