11 数据清洗工作

    技术2022-07-10  139

    # Author:Nimo_Ding ''' 数据分析师的数据清洗占据了80%的时间。 没有高质量的数据,就没有高质量的数据挖掘,而清洗是高质量数据的一道保障。 养成数据审核的习惯非常重要。 数据清洗规则: 完全合一 完整性:单条数据是否存在空值,统计的字段是否完善。 全面性:观察某一列的全部数值,看平均值 最大值 最小值来判断该列是否有问题。比如数据定义 单位标识 数值本身。 合法性:数据类型 内容 大小的合法性,比如数据中存在非ASCII字符,性别存在了未知,年龄超过120岁等。 唯一性:数据是否存在重复记录 # fillna 后面inplace参数的取值:True、False # True:直接修改原对象 # False:创建一个副本,修改副本,原对象不变(缺省默认) ''' print('\n# 1、完整性') # 缺失值 # 年龄体重缺失,由于数据量较大,这些数值没有被采集到,通常我们有三种解决方法: # 删除数据缺失的记录 # 使用当前列的均值代替 # 使用当前列出现频率最高的数据代替。 import numpy as np import pandas as pd from pandas import Series,DataFrame data = { 'name':['nimo','jack','ross','zijie'], 'age':[23,34,45,None] } df=DataFrame(data, columns=['name','age']) df.loc[0,'age']=34 # 使得第一行第二行的age相等。 print(df) ''' 结果: name age 0 nimo 34.0 1 jack 34.0 2 ross 45.0 3 zijie NaN ''' print('\n# 用平均年龄填充:') # df['age'].fillna(df['age'].mean(),inplace=True) print('\n# 用最高频的数据进行填充,value_counts对每个值进行计数,index第1个就是最高频的。') age_maxf=df['age'].value_counts().index[0] df['age'].fillna(age_maxf,inplace=True) print(df) ''' 结果: name age 0 nimo 34.0 1 jack 34.0 2 ross 45.0 3 zijie 34.0 ''' print('# 处理全空的空列') df['test']=np.nan print(df) # 结果: # name age test # 0 nimo 34.0 NaN # 1 jack 34.0 NaN # 2 ross 45.0 NaN # 3 zijie 34.0 NaN df=df.dropna(axis=1) print(df) ''' 结果: name age 0 nimo 34.0 1 jack 34.0 2 ross 45.0 3 zijie 34.0 ''' print('\n# 2、全面性') print('\n# 问题:列数据weight的单位不统一:kgs\lbs') df=DataFrame({ 'num':[1,2,3,4,5,None,6,7], 'name':['nimo ding','jack wang','ross li','zijie t','hello k',None,'world','hi'], 'age':[23,34,None,45,34,None,45,65], 'weight':['70kgs','154lbs',None,'78kgs','189lbs',None,'67kgs','45kgs'] }) print(df) ''' 结果: num name age weight 0 1.0 nimo ding 23.0 70kgs 1 2.0 jack wang 34.0 154lbs 2 3.0 ross li NaN None 3 4.0 zijie t 45.0 78kgs 4 5.0 hello k 34.0 189lbs 5 NaN None NaN None 6 6.0 world 45.0 67kgs 7 7.0 hi 65.0 45kgs ''' print('\n# 获取weight数据列中单位为lbs的数据') row_with_lbs=df['weight'].str.contains('lbs').fillna(False) print(df[row_with_lbs]) # 结果为: # num name age weight # 1 2.0 jack wang 34.0 154lbs # 4 5.0 hello k 34.0 189lbs # 将单位磅lbs转化为千克kgs: for i,lbs_row in df[row_with_lbs].iterrows(): weight=int(float(lbs_row['weight'][:-3])/2.2) df.at[i,'weight']='{}.kgs'.format(weight) print(df) print('\n# 3、合理性:包含了非ASCII字符,删除或替换掉。我的例子中好像没有?') df['name'].replace({r'[^\x00-\x7F]+':''},regex=True,inplace=True) print('\n# 4、唯一性') # 问题:一列有多个参数,name列可以拆分为firstname和lastname # 拆分之后再将name列删除 df[['firstname','lastname']]=df['name'].str.split(expand=True) df.drop('name',axis=1,inplace=True) print(df) # 结果: # num age weight firstname lastname # 0 1.0 23.0 70kgs nimo ding # 1 2.0 34.0 70.kgs jack wang # 2 3.0 NaN None ross li # 3 4.0 45.0 78kgs zijie t # 4 5.0 34.0 85.kgs hello k # 5 NaN NaN None None None # 6 6.0 45.0 67kgs world None # 7 7.0 65.0 45kgs hi None # 问题:重复数据 # 删除 df.drop_duplicates(['firstname','lastname'],inplace=True) print('\n# 作业:如下美食数据请做清洗') # ounces盎司 重量 df=DataFrame({ 'food':['bacon','pulled pork','bacon','Pastrami','corned beef', 'Bacon','pastrami','honey ham','nova lox'], 'ounces':[4,3,np.nan,6,7.5,8,-3,5,6], 'animal':['pig','pig','pig','cow','cow','pig','cow','pig','salmon'] }) print(df) # 结果: # food ounces animal # 0 bacon 4.0 pig # 1 pulled pork 3.0 pig # 2 bacon NaN pig # 3 Pastrami 6.0 cow # 4 corned beef 7.5 cow # 5 Bacon 8.0 pig # 6 pastrami -3.0 cow # 7 honey ham 5.0 pig # 8 nova lox 6.0 salmon print('\n# 1、全面性:food统一变成小写') df['food']=df['food'].str.lower() print(df) print('\n# 2、唯一性:删除重复行') # 可放到最后一步骤 df.drop_duplicates() print(df) print('\n# 3、合法性,将ounces中负值删除') print(df[df['ounces']<0].index) df=df.drop(df[df['ounces']<0].index) print(df) # df=df[df['ounces']>0] # 保留ounces>0的数据 print('\n# 4、完整性,将nan值替换成平均值') df['ounces'].fillna(round(df['ounces'].mean(),1),inplace=True) print(df) # 最后将索引重新生成 df=df.reset_index(drop=True) print(df)
    Processed: 0.009, SQL: 9