signed

QiShunwang

“诚信为本、客户至上”

Anacoda&Jupyter DAY 03 处理丢失数据&pandas层次化索引&pandas拼接操作

2020/8/19 21:01:27   来源:

Anacoda&Jupyter DAY 03 重点知识总结 处理丢失数据&pandas层次化索引&pandas拼接操作

一 处理丢失数据

一共有两种丢失数据:
None
np.nan(NaN)

  1. None
    None是python自带的 其类型为python object 因此 None不能参与到任何计算当中
    object类型的运算会比int类型的运算会慢很多
  2. np.nan(NaN)
    np.nan是浮点类型 能参与到计算中 但是参与到计算中的结果总是为nan
    我们可以使用 np.nan* 函数方法来计算nan 此时nan会被跳过计算(注意 这里的nan不能说被看作是0 因为如果看作是0 那么求得的平均数将会不准确 根据尝试可知 此函数使用的方法中 并不是将nan看作是0 而是直接掠过nan的这样项)
  3. pandas中的None和NaN
    1. pandas中的None和np.nan 都被视作为np.nan
      当我们创建表格 对某一个值进行更改为None或者nan的时候 打印出来的类型都为float
      但是 如果我们设定表格的时候使用的dtype是object 那么显示出来的就会不一样 None和NaN 就会分别显示开 (虽然如此 我们一般来说都不会刻意去使用dtype = object)
    2. pandas中None和np.nan 的操作
      isnull() 判断是否为nan 如果是 返回的是True
      notnull() 判断是否为nan 如果不是 返回的是True
      dropna() : 过滤丢失的数据
      fillna() : 填充丢失的数据
      1. df.isnull().any()
        df.notnull().all()
        any: 有true则为true 类似于or
        all: 所有的都为True才为True 类似于and
        该代码的输出为 每一列 对应布尔类型
      2. 过滤函数 dropna()
        可以过滤行和列 (默认的是行)
        1. df.dropna() # 默认删除有nan的行
          df.dropna(axis = 1) 删除有空的列
        2. 可以选择过滤模式 how = ‘all’ : 所有的值都为nan 才会删除这一行
          how = ‘any’ : 只要有一个为nan 那么就会删掉这一行或者这一列
      3. 填充函数 fillna()
        1. df.fillna(value = 10)
          将所有的nan的值转换为10
        2. df.fillna(method = ‘ffill’,axis = 0)
          method : ffill == forward fill 前补充,
          bfill == back fill 后补充
          axis : 控制行或者列 0是列 1是行
          连起来 如果df.fillna(method = ‘ffill’,axis = 0) 表示的就是 如果该数为nan则使用上面的数进行填充
          tips:
          1. 如果上面的数也是nan 那么就使用上面的上面的数进行填充
          2. 如果上面是边界 那么就会还是nan
        3. limit= : 限制每一行 或者 每一列改动的最大个数

二 pandas层次化索引

  1. 创建多行索引
    1. 隐式构造
      最常见的方法就是给DataFrame构造函数的index函数传递两个或者更多的数组
      ‘’’
      data = np.random.randint(0,100,size = (6,6))
      index = [
      [‘classone’,‘classone’,‘classone’,‘classtwo’,‘classtwo’,‘classtwo’],
      [‘张三’,‘李四’,‘王五’,‘赵六’,‘田七’,‘孙八’]
      ]
      columns = [
      [‘期中’,‘期中’,‘期中’,‘期末’,‘期末’,‘期末’],
      [‘语文’,‘数学’,‘英语’,‘语文’,‘数学’,‘英语’]
      ]
      df = DataFrame(data = data, index = index , columns = columns)
      ‘’’
      1. 显式构造 pd.MultiIndex
        1. 使用数组
          ‘’’
          data = np.random.randint(0,100,size = (6,6))
          index = pd.MultiIndex.from_arrays([
          [‘classone’,‘classone’,‘classone’,‘classtwo’,‘classtwo’,‘classtwo’],
          [‘张三’,‘李四’,‘王五’,‘赵六’,‘田七’,‘孙八’]
          ])
          columns = [
          [‘期中’,‘期中’,‘期中’,‘期末’,‘期末’,‘期末’],
          [‘语文’,‘数学’,‘英语’,‘语文’,‘数学’,‘英语’]
          ]
          df2 = DataFrame(data = data, index = index , columns = columns)
          ‘’’

        2. 使用元组 tuple
          ‘’’
          data = np.random.randint(0,100,size = (6,6))
          index = pd.MultiIndex.from_tuples(
          (
          (‘classone’,‘张三’),(‘classone’,‘李四’),(‘classone’,‘王五’),
          (‘classtwo’,‘赵六’),(‘classtwo’,‘田七’),(‘classtwo’,‘孙八’)
          )
          )
          columns = [
          [‘期中’,‘期中’,‘期中’,‘期末’,‘期末’,‘期末’],
          [‘语文’,‘数学’,‘英语’,‘语文’,‘数学’,‘英语’]
          ]

          df3 = DataFrame(data = data, index = index , columns = columns)
          ‘’’

        3. 使用product # 最简单的创建方法 但是会创建笛卡尔积
          ‘’’
          data = np.random.randint(0,100,size = (6,6))
          index = pd.MultiIndex.from_product([
          [‘classone’,‘classtwo’],
          [‘张三’,‘李四’,‘王五’]
          ])
          columns = pd.MultiIndex.from_product([
          [‘期中’,‘期末’],
          [‘语文’,‘数学’,‘英语’]
          ])
          df4 = DataFrame(data = data, index = index , columns = columns)
          ‘’’

        4. tips: 不管是显示创建 还是隐式创建 都需要记住一点 在上面创建的list将是最外层的索引 然后依次向内延展

  2. 多层列表索引
    除了行索引 index 列索引columns也能用同样的方法创建多层索引
  3. 多层索引对象的索引和切片的操作
    1. Series的操作
      对于Series来说 直接中括号[]和使用.loc[]的方法完全相同 但是这里推荐所有的切片都是用loc函数进行
      1. 显示操作
        1. 取值
          s[‘classone’][‘张三’]
          s.loc[‘classone’,‘张三’] # 和上面的相同 输出的都是一个数
          s.loc[‘classone’] # 只打印内层索引和数据
          s.loc[[‘classone’]] # 打印classone 和 内层索引 以及数据
        2. 切片
          s.loc[‘classone’:‘classtwo’]
          s.loc[‘classone’][‘张三’:‘李四’]
          s.loc[‘classone’:‘classtwo’][‘张三’:‘赵六’] # 这样有跨度的显式索引不可以实现 但是隐式索引可以
      2. 隐式索引
        大多数操作与显式索引操作相同 可以举一反三
        但是显式索引不能有跨度的操作 而隐式索引可以(隐式索引可以不用管 外层索引还是内层索引 所有的部分都是以类似于坐标的形式实现 这点也是为什么可以有跨度的原因之一)
    2. DataFrame的操作
      1. 显式操作
        df.loc[‘classone’,‘李四’][‘期中’,‘数学’]
        df.loc[(‘classone’,‘李四’),(‘期中’,‘数学’)]
        tips: 不管是显示还是隐式 如果使用loc(iloc)函数方法 都是从行索引开始取 之后再取列索引
      2. 使用行索引需要使用loc等函数
        推荐使用loc函数 注意再对行索引的时候 若一级行索引还有多个 对二级行索引可能会遇到问题 也就是说 无法直接对耳机索引进行索引 必须让耳机索引变成一级索引才能对其进行索引
  4. 索引的堆 (stack)
    stack()
    unstack()
    小技巧:
    1. 使用stack()的时候 level等于哪一个 哪一个就会消失 并成为行索引 (最里层)
    2. 使用unstack的时候 level等于哪一个 哪一个就会消失 并成为列索引 (最里层)
    3. level = # 从最外层的开始数 最外层为0 依次向内+1 默认值level = -1 就是最内侧的索引
      df.T 可以对行列进行置换 (T: transpose)
  5. 聚合操作
    以df.sum() 举个例子
    df.sum(axis = 1,level = 1)
    小贴士:
    1. axis等于谁 那么行或者列 就不变 其他的聚合
      如 axis = 1 那么行的索引不变 列索引聚合
    2. level控制另外一个的索引 比如这里写的是axis = 1,level = 1
      axis = 1表示列将会收到聚合 那么level = 1 就表示参照的是内层的列索引 (即 保留内层列索引 外层列索引消失 进行聚合)

三 pandas的拼接操作 [pd.concat级联]

  1. 回顾numpy的级联
    1. np.concatenate() 级联两个或者两个以上numpy对象 通过axis控制拼接的方向
      tips: concatenate() 函数不会创建新层级 比如两个一维数组需要上下拼接 拼接成的结果必然是二维列表 但是由于concatenate的函数特性 这样的操作必然会报错 但是下面所说的vstack方法就不会报错 vstack函数会创建新的维度
    2. vstack vertical 垂直拼接
    3. hstack horizontal 水平拼接
  2. 使用pd.concat() 拼接
    pandas使用的pd.concat函数 , 与 np.concatenate函数类似 多了一些参数
    objs # objects
    axis = 0 # 级联方向
    join = ‘outer’ (or ‘inner’ ) # 外连接或者内连接 外连接将会保留所有值 如果无值 则会使用NaN来填充给 内连接只有在连接的两者匹配的情况下才会显示
    join_axes = None (left_pd,right_pd) # 拼接后显示的列是所有左边的所有的列 还是右边的所有列 如果是None 则显示所有
    ignore_index = False # 如果是True 那么将会遗忘之前的行索引 进行从0开始至n-1重新索引
    keys=[value1,value2 …] # 使用多层索引keys
    1. 不匹配级联[着重需要理解]
      不匹配指的是级联的维度的所有不一致 例如纵向级联时列索引不一致 横向索引的时候不一致
      三种连接方式:
      1. 外连接 : (默认模式) 没有值的部分使用NaN来补齐
      2. 内连接 : join = ‘inner’ 只连接匹配的项
      3. 连接指定的轴: join_axes = [] # # 拼接后显示的列是所有左边的所有的列 还是右边的所有列 如果是None 则显示所有