pandas 数据清洗(数据组合)

数据组合

2.1.1 concat【重点】

  • pandas函数,pd.concat()

  • 既可以纵向连接(默认,axis=0或者axis=‘index’)也可以横向连接(axis=1或者axis=‘columns’)

  • 可以连接多个对象(多个df)

  • 纵向连接:N个df从上到下一个摞一个

    • 默认外连接(join=‘outer’),列名相同的数据会合并到一列,列名不同的数据用NaN填充
    • 内连接(join=‘inner’),只保留数据中共有的部分
  • 横向连接:N个df从左到右一个挨着一个

    • 默认外连接(join=‘outer’),匹配各自行索引,缺失值用NaN
    • 内连接(join=‘inner’),只保留索引匹配的共有数据
  • api介绍

    pd.concat([df1,df2,df3...],axis=,join='',ignore_index=)
    
    # df之间用list传入
    # 默认纵向连接,axis=0或者'index';横向连接axis=1或者'columns'
    # ignore_index默认为False,不重置索引,保留各自df索引;等于True,重置索引0,1,2,3,4...
    

2.1.2 append【掌握】

  • 只能纵向连接

  • 向现有的df追加一个对象(可以是df,也可以是字典,追加字典时ignore_index=True)

  • api用法

    # 追加df对象
    # 参数ignore_index默认为False,保留各自df索引;等于True重置索引0,1,2,3,4...
    df1.append(df2,ignore_index=)
    
    # 追加字典对象
    # ignore_index必须等于True,否则报错无法追加字典
    df1.append(dict,ignore_index=True)
    

2.1.3 merge【重点】

  • DataFrame方法,df1.merge(df2)

  • 只能横向连接两个df对象,类似mysql 的join连接

  • 通过指定列的值相等横向合并df1和df2,然后返回新的df3,df3可以继续和df4合并

  • 默认是内连接(也可以设置为左连接,外连接,右连接)

  • api用法

    pd.merge(df1,df2,on='',how='')
    # 或者
    df1.merge(df2[['列名1', '列名2', ...]],on='',how='')
    
    # 参数on='列名',表示基于哪一列进行合并操作
    # 参数how='固定值',表示合并后如何处理行索引,固定参数具体如下:
    # how=’left‘ 对应SQL中的left join,保留左侧表df1中的所有数据
    # how=’right‘ 对应SQL中的right join,保留右侧表df2中的所有数据
    # how='outer' 对应SQL中的join,保留左右两侧侧表df1和df2中的所有数据
    # how='inner' 对应SQL中的inner,只保留左右两侧df1和df2都有的数据,默认inner
    

2.1.4 join【掌握】

  • DataFrame方法,df1.join(df2)

  • 只能横向合并,合并时可以依据两个df的行索引,或者一个df的行索引另一个df的列索引进行数据合并

  • 默认是左连接(也可以设置为左连接,外连接,右连接)

  • api用法

    # 依据两个df的行索引合并
    # 当两个df有相同列名的列时,需要通过lsuffix和rsuffix给左右两个df相同列的列名添加后缀,否则报错
    # how用法和merge一致
    df1.join(df2,lsuffix='', rsuffix='', how='')
    
    # 依据一个df的行索引另一个df的列索引进行数据合并
    # 括号里面为设置行索引的df2,括号外边为列索引的df1
    # on='列名',为df1与df2行索引合并的列索引
    df1.join(df2,lsuffix='', rsuffix='', how='',on='')
    

2.2 缺失数据处理

2.2.1 NaN介绍以及加载【知道】

  • 缺失值和其它类型的数据不同,它毫无意义,NaN不等于0,也不等于空字符串,两个NaN也不相等

  • 检测某个值是否为缺失值

    # 当为缺失值时返回True,否则返回False
    pd.isnull()
    pd.isna()
    
    # 当为缺失值时返回False,否则返回True
    pd.notnull()
    pd.notna()
    
  • 加载包含缺失的数据

    pd.read_csv('path',na_values=,keep_default_na=)
    # na_values,指定数据的值为缺失值
    # keep_default_na,默认True,显示默认缺失值;False不显示默认缺失值
    
  • 缺失值产生的原因

    • 原始数据包含缺失值
    • 数据整理过程中(merge,join)产生缺失值

2.2.2 查看缺失值【了解】

  • Missingno库 pip install missingno

    import missingno as msno
    
    # 查看数据集数据的完整性
    msno.bar(df)
    
    # 快速直观的查看缺失值的分布情况
    msno.matrix(df)
    
    # 查看缺失值之间是否具有相关性
    msno.heatmap(df)
    

2.2.3 缺失值处理【重点】

  • 删除缺失值

    • 删除缺失值会损失信息,并不推荐删除,当缺失数据占比较低的时候,可以尝试使用删除缺失值

    • 按行删除

      # 函数用法
      df.dropna(axis=0, how='any', subset=['列名',...], inplace=True, thresh=n)
      
      # 参数解释
      #可选参数subset,不与thresh参数一起使用
      接收一个列表,列表中的元素为列名: 对特定的列进行缺失值删除处理
      
      #可选参数thresh=n
      参数值为int类型,按行去除NaN值,去除NaN值后该行剩余数值的数量(列数)大于等于n,便保留这一行
      
      #可选参数 axis=0
      0, or 'index':删除包含丢失值的行
      1, or 'columns':删除包含丢失值的列
      默认为0
      
      #可选参数 how='any',与inplace=True参数一起使用
      'any': 如果存在NA值,则删除该行或列
      'all': 如果所有值都是NA,则删除该行或列
      默认为'any'
      #可选参数inplace=False
      默认False,不在源文件上删除
      inplce=True,在源文件上删除
      
    • 按列删除

      df.drop(['列名',..], axis=1,inplace=)
      
      # axis默认等于0,按行删除;axis=1,按列删除
      # inplace默认等于False,不在源文件上删除;等于True,在源文件上删除
      
  • 填充缺失值

    • 非时间序列数据填充缺失值,使用常量或者统计量替换缺失值

      # 使用常量
      df.fillna(0,inplace=True)
      
      # 使用统计量(缺失值所处列的平均值、中位数、众数)
      df['列名'].fillna(df['列名'].聚合函数(), inplace=True)
      
    • 时间序数据缺失值处理

      • 用时间序列中空值的上一个非空值填充

        df.fillna(method='ffill',inplace=True)
        
      • 用时间序列中空值的下一个非空值填充

        df.fillna(method='bfill',inplace=True)
        
      • 线性插值方法

        • 绝大多数的时序数据,具体的列值随着时间的变化而变化。 因此,使用bfill和ffill进行插补并不是解决缺失值问题的最优方案。
        • 线性插值法是一种插补缺失值技术,它假定数据点之间存在严格的线性关系,并利用相邻数据点中的非缺失值来计算缺失数据点的值。
        df.interpolate(limit_direction="both", inplace=True)
        

2.3 数据整理【知道】

宽数据集变形为长数据集的方式有三种:

  • melt 将指定的一个或多个列名变成一个列的值
  • stack 将所有列名变为一列的值
    • unstack是stack的反向操作
  • wide_to_long 将列名起始部分相同的列进行拆解

2.3.1 melt函数将指定的一个或多个列名变成一个列的值

pd.melt(
    df,
    id_vars=['列名'], # 不变形的所有列
    value_vars=['列名'], # 要变形的所有列:把多个列变成一个新列(variable);同时所有对应的值变成第二个新列的值(value)
    var_name='新列名', # 新列的列名
    value_name='新列名' # 第二个新列的列名
)

# 指定id_vars参数,返回的df中包含不变形的列和变形的列
# 指定value_vars参数,返回的df中只包含变形的列,不存在未变形的列

2.3.2 stack将所有列名变为一列的值

s = df.stack() # 返回层级索引的series对象
s.reset_index() # 转为df
s.rename_axis() # 给不同的行索引层级命名
s.unstack() # stack的反向操作,返回df对象

2.3.3 wide_to_long函数处理列名带数字后缀的宽数据

pd.wide_to_long(
	  df,
    stubnames=['列名开头字符串'], # 要处理的列名开头,提取以指定字符串开头的列,可以是多个
    i=['列名'],  # 指定作为行索引的列名
    j='列名',  # 提取列名开头后剩余的部分(数字部分)会成一列,在此指定列名
    sep='' # 指定列名中的分隔符
)

2.4 Pandas数据类型

2.4.1 pandas有哪些数据类型【知道】

  • pandas是基于numpy构建的包,所以pandas中的数据类型都是基于Numpy中的ndarray类型实现的
  • Pandas中的数据结构对象和数据类型对象:
    • dataframe 表 【数据结构】
      • series 列【数据结构】
        • object --> python str 字符串 【数据类型】
        • int64 --> python int 整数 【数据类型】
        • float64 --> python float 小数 【数据类型】
        • datetime64 --> python datetime 时间日期 【数据类型】
        • bool --> python bool True False 【数据类型】
        • timedelta[ns]–> 两个时间点之间相距的时间差,单位是纳秒 【数据类型】
        • category --> 特定分类数据类型,比如性别中分为男、女、其他 【数据类型】

2.4.2 类型转换【掌握】

  • astype()

    • 注意特殊情况:使用astype函数转换目标为数值类型时,astype函数要求DataFrame列的数据类型必须相同。当有些数据中有缺失,但不是NaN时(如’missing’,'null’等),会使整列数据变成字符串类型而不是数值型
      • 这种情况用to_numeric函数
    # 转换为字符串类型
    df['列名'].astype(str)
    
    # 转换为数值类型
    df['列名'].astype(int)
    df['列名'].astype(float)
    
  • to_numeric()

    • 能够将series对象中的数据转换为数值类型,比如int,float
    pd.to_numeric(df['列名'],errors='',downcast='')
    

    参数说明

    • errors 它决定了当该函数遇到无法转换的数值时该如何处理
      • 默认值为raise, 如果to_numeric遇到无法转换的值时,会抛错
      • coerce: 如果to_numeric遇到无法转换的值时,会返回NaN
      • ignore: 如果to_numeric遇到无法转换的值时会放弃转换,什么都不做
    • downcast参数能够让数据存储空间尽量的变小
      • 默认是none,接受的参数值为integerfloat
      • downcast='float'为例,float子型态有float16,float32,float64,所以设置了downcast=float,则会将数据转为能够以较少bytes去存储一个浮点数的float16
    • 注意:downcast参数和errors参数是分开的,如果downcast过程中出错,即使errors设置为ignore也会抛出异常

2.4.3 category分类数据类型【知道】

  • category是什么

    • 比较特殊的数据类型,是由固定的且有限数量的变量组成的,比如性别,分为男、女、保密;转换方法可以使用astype函数
    • category类型的数据中的分类是有顺序的
  • 创建category类型的数据

    • 方法一

      s = pd.Series(
          pd.Categorical(
              ["a", "b", "c", "d"], # series的数据
              categories=["c", "b", "a"] # 指定有几个类别,当数据中出现与类别匹配的数据,返回NaN
          )
      )
      
      s
      # 输出结果如下
      0      a
      1      b
      2      c
      3    NaN
      dtype: category
      Categories (3, object): ['c', 'b', 'a']
      
    • 方法二

      series_cat = pd.Series(['B','D','C','A'], dtype='category') # 通过dtpye指定类别类型
      
      series_cat
      # 输出结果如下
      0    B
      1    D
      2    C
      3    A
      dtype: category
      Categories (4, object): ['A', 'B', 'C', 'D']
      
  • 通过CategoricalDtype指定category数据的类型顺序

    from pandas.api.types import CategoricalDtype
    # 构造category数据类型的顺序对象
    cat = CategoricalDtype(categories=['B','D','A','C'], ordered=True)
    # 将category数据类型的顺序对象赋予series_cat这个数据
    series_cat1 = series_cat.astype(cat)
    
  • 通过categories类型的series对象.cat.reorder_categories()方法修改排序规则

    series_cat.cat.reorder_categories(
        ['D','B','C','A'], # 重新设定类型值的顺序
        ordered=True, # 设定有顺序
        inplace=True  # inplace参数设置为True,让本次设定生效,变动覆盖原数据
    )
    
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值