数据清洗的概念
类比定义
数据分析过程 做菜过程
收集数据 明确要做什么菜品
数据清洗 去菜市场买菜
数据分析 炒菜
数据分析报告+数据可视化 拍照+发朋友圈并且吃菜
专业定义
数据清洗是从记录表、表格、数据库中检测、纠正或删除损坏或不准确的记录过程
专业名词
脏数据
没有进过处理自身有一定问题的数据(缺失、异常、重复。。。)
干净数据
经过处理完全符合规范要求的数据
常用方法
1.读取外部数据
read_csv
read_excel
read_sql
read_html
2.数据概览
index columns head tail shape descibe info dtypes
3.简单处理
移除收尾的空格 大小写转换
4.重复值处理
duplicated()查看是否有重复的数据
drop_duplicates()删除重复数据
5.缺失值处理
删除缺失值、填充缺失值
6.异常值的处理
删除异常值、修正异常值
7.字符串处理
切割、筛选
8.时间格式处理
Y m d H M S
步骤3到步骤8没有固定的顺序 前期由于不是非常熟练的情况下可以按照上述步骤来执行
数据概览
import numpy as np import pandas as pd import matplotlib.pyplot as plt df = pd.read_csv(r'qunar_freetrip.csv') # 1.查看前五条数据 掌握大概 df.head() # 2.查看表的行列总数 df.shape # 3.查看所有的列字段 df.columns # 发现列字段有一些是有空格的 # 4.查看数据整体信息 df.info() # 发现去程时间和回程时间是字符串类型需要做日期类型转换 # 5.快速统计 df.describe() df.columns
列字段处理
刚开始拿到数据的时候无用的字段可能无法删除,因为字段名称中可能包含了空格
下列造作是在找出首尾含有空格的字段并且移除首位的空格
# 1.删除无用列字段 # df.drop(columns='Unnamed: 0',axis=1,inplace=True) # 2.获取列字段 cols = df.columns.values # 3.for循环依次取出列字段首位的空格 # 方式1 比较繁琐 # ccs = [] # for col in cols: # ccs.append(col.strip()) # print(ccs) # 方式2 列表生成式 df.columns = [col.strip() for col in cols]
重复值处理
# 4.重复数据查找 # df.duplicated() # 5.简单的楼一眼重复数据的模样(布尔值索引) 可以省略 # df[df.duplicated()] # 6.针对重复的数据 一般情况下都是直接删除的 # df.drop_duplicates(inplace=True) # 7.确认是否删除 # df.shape # 8.行索引会不会因为数据的删除而自动重置(删除完数据之后行索引是不会自动重置的) ## 如何获取表的行索引值 # df.index ## 右侧加上赋值符号就是修改行索引值 # df.index = range(0,df.shape[0]) df.tail()
异常值处理
利用快速统计大致筛选出可能由异常数据的字段
df.describe() # 价格小于节省 那么可能是价格有问题或者节省有问题
利用公式求证我们的猜想
sd = (df['价格'] - df['价格'].mean()) / df['价格'].std() # 判断的标准 # 利用逻辑索引筛选数据 df[(sd > 3)|(sd < -3)] # 利用绝对值 df[abs(sd) > 3] # abs就是绝对值的意思(移除正负号)
同理验证节省数据是否有异常(不一定要使用)
# sd1 = (df['节省'] - df['节省'].mean()) / df['节省'].std() # 判断的标准 # 利用逻辑索引筛选数据 # df[(sd > 3)|(sd < -3)] # 利用绝对值 # df[abs(sd1) > 3] # abs就是绝对值的意思(移除正负号)
直接简单粗暴找节省大于价格的数据(推荐下列的方式)
df[df['节省'] > df['价格']]
删除价格和节省都有异常的数据
方式1:先拼接在一次性删除
横向合并pd.merge()
纵向合并pd.concat()
res = pd.concat([df[df['节省'] > df['价格']],df[abs(sd) > 3]])
获取要删除的行数据 索引值
del_index = res.index
根据索引删除数据
df.drop(index=del_index,inplace=True)
再次重置索引
df.index = range(0,df.shape[0])
方式2:得出一个结果就删一个
出发地缺失值处理
查找具有缺失值的列名称
df.isnull().sum() # 统计每个字段缺失数据条数
利用布尔值索引筛选出出发地有缺失的数据
df[df.出发地.isnull()]
获取出发地缺失的数据的路线数据利用字符串的切割替换出发地缺失数据
df.loc[df.出发地.isnull(),'路线名'].values
利用字符串切割操作替换出发地缺失数据
df.loc[df.出发地.isnull(),'出发地'] = [i.split('-')[0] for i in df.loc[df.出发地.isnull(),'路线名'].values]
操作数据的列字段需要使用loc方法
针对缺失值的处理
1.采用数学公式依据其他数据填充
2.缺失值可能在其他单元格中含有
3.如果缺失值数量展示很小可删除
目的地缺失值处理
针对与目的地的操作如上述(筛选数据会比出发地要难)
df[df.目的地.isnull()]
获取前目的地缺失的路线数据
df.loc[df.目的地.isnull(),'路线名'].values
利用正则筛选出目的地
import re reg_exp = '-(.*?)\d' # res = re.findall(reg_exp,'深圳-秦皇岛3天2晚 | 入住大连黄金山大酒店 + 南方航空/东海往返机票')
df.loc[df.目的地.isnull(),'目的地'] = [re.findall(reg_exp,i) for i in df.loc[df.目的地.isnull(),'路线名'].values]
缺失值处理讲解
计算缺失值数据的占比
df.isnull().sum()/df.shape[0] # 我们自己规定占比小于0.1%可以直接删除
针对缺失数据有几种处理方式
1.占比过小可以直接删除
2.利用均值、统一值直接填充
3.根据不同的情况采用不同的计算公式填充
常见的四个方法:
1.isnull
2.notnull
3.fillna
4.dropna
保留几位小数
round(数据,保留几位)
筛选出所有价格缺失的数据
df[df['价格'].isnull()]
直接利用价格的均值填充数据
df['价格'].mean() # 1732.5140901771338 round(df['价格'].mean(),1) df['价格'].fillna(round(df['价格'].mean(),1),inplace=True)
同理针对节省的数据也做中位数填充(其实应该结合实际采用不同的的方法)
df['节省'].fillna(round(df['节省'].mean(),1),inplace=True)
验证
df.isnull().sum()
补充
MySQL中如何快速的判断某列是否含有重复的数据
思路:就是统计某个字段下数据的个数 在利用气冲操作两者结合判断
select count(name) from userinfo; select count(distinct(name)) from userinfo;
如果两者数字相同表示没有重复的数据
不同表示存在重复的数据
作业
import numpy as np import pandas as pd import matplotlib.pyplot as plt import re
df=pd.read_csv('qunar_freetrip.csv')
list=[] res=df['酒店'] reg_exp1=' (.*?) ' for i in res: hotel_type=re.findall(reg_exp1,i) if not hotel_type: t1='暂无' else: t1=hotel_type[0] list.append(t1) df['酒店类型']=list list2=[] res=df['酒店'] for n in res: t2=n.split('/')[0] hotel_score=t2.split(' ')[-1] list2.append(hotel_score) df['酒店评分']=list2 list3=[] res=df['路线名'] for time in res: t3=time.split('|')[0] travel_time=t3.split('-')[1][-5:-1] list3.append(travel_time) df['游玩时间']=list3