数据分析基础篇16讲之11数据科学家80%时间都花费在了这些清洗任务上?

11 数据科学家80%时间都花费在了这些清洗任务上?

假如采集的数据如下图所示:

在这里插入图片描述

如果刚看到这些数据可能我们无法下手,因为这些数据中都没有标注,所以我们对这些数据进行重新整理。

  • 首先这些数据的代表含义是:这是一家服装店的会员数据,最上一行是列坐标,最左侧一列是行坐标
  • 列坐标中第0列代表的是序号,第1列代表的是会员姓名,第2列代表的是年龄,第3列代表体重,第46列代表男性会员三围尺寸,第79列代表女性会员三围尺寸。
数据质量的准则
  • 看到这些数据,我们会想到,应该用什么规则来规范这些数据的质量呢?
  • 在这里将清洗规则总结为以下4个关键点,统一起来叫“完全合一”,那么什么意思呢?
    • 1.整性:单条数据是否存在空值,统计的字段是否完整。
    • 2.面性:观察某一列的全部数值,如在Excel中,我们可选中一列,可以看到该列的平均值、最大值、最小值。也可通过常识来判断该列是否存在问题,如:数据定义、单位的标识、数值本身。
    • 3.法性:数据的类型、内容、大小的合法性。比如数据中存在非ASCII字符,性别存在未知,年龄超过了150岁等。
    • 4.唯性:数据是否存在重复记录,因为数据来自于不同来源的汇总,很有可能发生重复。行、列数据都需要是唯一的,比如一个人不能重复记录多次,且一个人的体重也不能在列指标中重复记录多次。
清洗数据,一一击破
1. 完整性
  • 问题1:缺失值
    • 在数据中有些年龄、体重数值是缺失的,这往往是因为数据量较大,在采集过程中,没有采集到。通常我们采用以下三种方法:

      • 删除:删除数据缺失的记录

      • 均值:适用当前列的均值

      • 高频:使用当前列出现频率最高的数据

      • 比如我们想对df[‘Age’]中缺失的数值用平均年龄进行填充,可以写成

        • df['Age'].fillna(df['Age'].mean(),inplace=True)
          
      • 如果用最高频的数据进行填充,可先通过value_counts获取Age字段最高频次age_maxf,然后再对Age字段中缺失的数据用age_maxf进行填充:

        • age_maxf=train_features['Age'].value_counts().index[0]
          train_features['Age'].fillna(age_maxf,inplace=True)
          
  • 问题2:空行
    • 我们发现数据中有一个空行,除了index之外,全部的值都是NaN。因为Pandas的read_csv()并没有可选参数忽略空行,所以还需要再数据被读取之后再使用dropna()进行处理,删除空行。

      • #删除全部空行
        df.dropna(how="all",inplace=True)
        
        
2. 全面性
  • 问题:列数据的单位不统一
    • 从数据中我们发现weight列的单位不统一,有的为千克(kgs),有的是磅(lbs)。我们采用将千克作为统一的度量单位,将磅(lbs)转化为千克(kgs)

      • # 获取 weight 数据列中单位为 lbs 的数据
        rows_with_lbs = df['weight'].str.contains('lbs').fillna(False)
        print df[rows_with_lbs]
        # 将 lbs 转换为 kgs, 2.2lbs=1kgs
        for i,lbs_row in df[rows_with_lbs].iterrows():
        	# 截取从头开始到倒数第三个字符之前,即去掉 lbs。
        	weight = int(float(lbs_row['weight'][:-3])/2.2)
        	df.at[i,'weight'] = '{}kgs'.format(weight) 
        
        
3. 合理性
  • 问题:非ASCII字符
    • 从数据集中我们发现在Firstname和Lastname有一些非ASCII字符。我们可以采用删除或替换的方法来解决,这里采用删除:

      • # 删除非 ASCII 字符
        df['First_Name'].replace({r'[^\x00-\x7F]+':''}, regex=True, inplace=True)
        df['Last_Name'].replace({r'[^\x00-\x7F]+':''}, regex=True, inplace=True)
        
        
4. 唯一性
  • 问题一:一列有多个参数
    • 在数据集中,姓名列(Name)由两个参数FirstName和LastName。为了数据的整洁,我们可将Name列设置为FirstName和LastName两个字段。使用python的split方法,str.split(expand=True),将列表拆成新的列,并删除原来的Name列

      • # 切分名字,删除源数据列
        df[['First_Name','Last_Name']] = df['Name'].str.split(expand=True)
        df.drop('Name', axis=1, inplace=True)
        
        
  • 问题二:重复数据
  • 利用Pandas提供的drop_duplicates()来删除重复数据。

    • # 删除重复数据行
      df.drop_duplicates(['First_Name','Last_Name'],inplace=True)
      
      
完整代码:
  • # 11. 数据科学家80%时间都发费在了这些清洗任务上
    # -*- coding: utf-8 -*-
    import pandas as pd
    from pandas import DataFrame
    df = pd.read_csv('./11data.csv',engine='python')
    # print(df)
    df = df.drop(columns=['Unnamed: 0'])
    
    
    df.rename(columns={'0': 'Index', '1': 'Name','2': 'Age','3': 'Weight',
    					'4': 'm0006','5': 'm0612','6': 'm1218',
    					'7': 'f0006','8': 'f0612','9': 'f1218'}, inplace = True)
    df = df.drop(columns=['Index'])
    # 1.完整性
    # 1.1 用平均年龄填充
    # df['Age'].fillna(df['Age'].mean(),inplace=True)
    
    # 1.2 采用最高频次的数据进行填充
    # age_maxf = df['Age'].value_counts().index[0]
    # df['Age'].fillna(age_maxf,inplace=True)
    
    # 1.3 删除空行
    df.dropna(how='all',inplace=True)
    
    # 2. 全面性
    # 2.1 列数据单位不统一
    # 获取weight数据列中单位为lbs的数据
    rows_with_lbs = df['Weight'].str.contains('lbs').fillna(False)
    # print(df[rows_with_lbs])
    # 将lbs转为kgs,2.2lbs=1kgs
    for i,lbs_row in df[rows_with_lbs].iterrows():
    	#截取从头开始到倒数第三个字符之前,即去掉lbs
    	weight = int(float(lbs_row['Weight'][:3])/2.2)
    	df.at[i,'Weight'] = '{}kgs'.format(weight)
    
    
    # 4. 唯一性 
    # 4.1 切分名字,删除源数据列
    df[['First_Name','Last_Name']] = df['Name'].str.split(expand=True)
    df.drop('Name', axis=1, inplace=True)
    
    
    # 3. 合理性
    # 删除非 ASCII 字符
    df['First_Name'].replace({r'[^\x00-\x7F]+':''}, regex=True, inplace=True)
    df['Last_Name'].replace({r'[^\x00-\x7F]+':''}, regex=True, inplace=True)
    
    # 4.2 删除重复数据
    df.drop_duplicates(['First_Name','Last_Name'],inplace=True)
    
    
    #显示所有列
    pd.set_option('display.max_columns', None)
    #显示所有行
    pd.set_option('display.max_rows', None)
    #设置value的显示长度为100,默认为50
    pd.set_option('max_colwidth',100)
    
    print(df)
    
    # 数据结果
    #      Age Weight m0006 m0612 m1218 f0006 f0612 f1218 First_Name Last_Name
    # 0   56.0  70kgs    72    69    71     -     -     -      Micky      Mous
    # 1   34.0  70kgs     -     -     -    85    84    76     Donald      Duck
    # 2   16.0    NaN     -     -     -    65    69    72       Mini     Mouse
    # 3    NaN  78kgs    78    79    72     -     -     -    Scrooge    McDuck
    # 4   54.0  89kgs     -     -     -    69   NaN    75       Pink   Panther
    # 5   52.0  85kgs     -     -     -    68    75    72       Huey    McDuck
    # 6   19.0  56kgs     -     -     -    71    78    75      Dewey    McDuck
    # 7   32.0  78kgs    78    76    75     -     -     -     Sc??py       Doo
    # 10  12.0  45kgs     -     -     -    92    95    87      Louie    McDuck
    
    
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值