目录
- 数据清洗的概念
- 数据清洗实战案例
数据清洗的概念
类比定义
数据分析过程 做菜过程 明确需求 >>> 明确做什么菜品 收集数据 >>> 去菜市场买菜 数据清洗 >>> 泽菜洗菜切菜 数据分析 >>> 炒菜 数据报告+数据可视化 >>> 拍照发朋友圈吃菜
专业定义
数据清洗是从记录表、表格、数据库中检测、纠正或者删除损坏或不准确记录的过程
专业名词
脏数据
没有经过处理自身含有一定问题的数据
干净数据
经过处理完全符合规范要求的数据
常用方法
1.读取外部数据 read_csv/read_excel/read_sql/read html 2.数据概览 index/columns/head/tail/shape/describe/info/dtypes 3.简单处理 移除字段名首尾空格,大小写转换... 4.重复值处理 duplicated() # 查看是否含有重复数据 drop_deplicates() # 删除重复数据 5.缺失值处理 删除缺失值,填充缺失值 6.异常值处理 删除异常值、修正异常值 7.字符串处理 切割、筛选... 8.时间格式处理 Y、m、d、H、M、S
数据清洗实战案例
数据读取
import numpy as np import pandas as pd import matplotlib.pyplot as plt df = pd.read_csv(r'qunar_freetrip.csv')
思路
1.查看前五条数据,掌握个大概 2.查看表的行列总数 3.查看所有的列字段 # 发现列字段有一些是有空格的 4.查看数据整体信息 # 发现去程时间和回程时间是字符串类型需要做日期类型转换 5.快速统计
列字段处理
1.删除无用列字段
df.drop(columns='Unnamed:0',axis=1,inplace=True)
2.获取列字段发现字段名内有空格
cols = df.columns.values
3.利用for循环依次取出列字段首尾空格
# 方法一 ccs = [] for col in cols: ccs.append(col.strip()) print(ccs)
# 方法二 利用列表生成式 df.columns = [col.strip() for col in cols]
重复值处理
1.重复数据查找
df.duplicated()
2.简单看一下重复数据的模样,通过布尔值索引
3.对于重复的数据,最常见的处理方式就是删除
df.drop_duplicates(inplace=True) df.shape # 确认是否一删除
4.删除之后发现原数据的行索引不会自动重置
5.解决措施就是先获取表的行索引值,在右侧加上赋值符号就是修改行索引
df.index df.index = range(0,df.shape[0]) df.tail()
补充
"""MySQL中如何快速判断某列是否含有重复的数据""" # 思路 就是统计某个字段下数据的个数载利用去重操作,两者结合判断 如果两者数字相同表示name列没有重复的数据,不同表示含有重复的数据
sql语句
select count(name) from userinfo; select count(distinct(name)) from userinfo;
异常值处理
1.可以先通过快速统计的方法筛选出可能有异常数据的字段
df.describe() # 发现价格小于节省,那么可能是价格或节省有问题
2.利用固定的算法公式去求证我们的猜想
# 判断的标准 sd = (df['价格'] - df['价格'].mean()) / df['价格'].std() # 利用逻辑索引筛选数据 df[(sd > 3)|(sd < -3)]
# 别忘了要移除正负号
df[abs(sd) > 3] # abs就是绝对值的意思
3.同理也可以筛选出节省的异常数据项(不一定要使用)
# 另一种更快的筛选节省异常数据的方式
df[df['节省'] > df['价格']]
4.删除价格和节省都有异常的数据
# 方式一 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 得出一个结果就删一个
出发地缺失值处理
1.查找具有缺失值得字段列名称
2.利用布尔值索引筛选出出发地有缺失的数据
3.获取出发地缺失的数据的路线数据
4.利用字符串切割替换出发地缺失数据
for i in res['路线名'].values: print(i.split('-')[0])
5.形成列表生成式简写上面的操作
并利用isnull方法查看出发地字段内是否有缺失数据
df.loc[df.出发地.isnull(),'出发地'] = [i.split('-')[0] for i in df.loc[df.出发地.isnull(),'路线名'].values]
总结
# 针对缺失值的处理 1.采用数学公式依据其他数据填充 2.缺失值可能在其他单元格中含有 3.如果缺失值数量展示很小可删除
目的地缺失值处理
1.利用布尔值索引筛选出出发地有缺失的数据
2.获取目的地缺失的路线数据
3.利用正则筛选出目的地
# 案例演示 reg_exp = '-(.*?)\d' # res = re.findall(reg_exp,'深圳-秦皇岛3天2晚 | 入住大连黄金山大酒店 + 南方航空/东海往返机票')
代码
import re for i in df.loc[df.目的地.isnull(),'路线名'].values: print(re.findall('-(.*?)\d',i)[0])
4.形成列表生成式简写上面的操作
并利用isnull方法查看出发地字段内是否有缺失数据
df.loc[df.目的地.isnull(),'目的地'] = [re.findall('-(.*?)\d',i) for i in df.loc[df.目的地.isnull(),'路线名'].values] df[df['目的地'].isnull()]
价格与节省缺失值处理
1.筛选出所有价格缺失的数据
2.直接利用价格的均值填充缺失数据
df['价格'].mean() round(df['价格'].mean(),1) df['价格'].fillna(round(df['价格'].mean(),1),inplace=True)
3.同理针对节省的数据也做中位数填充
df['节省'].fillna(round(df['节省'].mean(),1),inplace=True) # 验证 df.isnull().sum()
作业:
新增三个列,分别是酒店类型、酒店评分、游玩时间
# 定义一个空列表 hotel_type=[] # fpr循环 for i in df['酒店'].values: hotel_type.append(re.findall(' (.*?) ',i)) # 赋值 df['酒店类型'] = np.array(hotel_type) hotel_rating = [] for i in df['酒店'].values: # 正则方法 hotel_rating.append(re.findall('(\d.\d)分',i)) df['酒店评分'] = np.array(hotel_rating) play_time = [] for i in df['路线名'].values: play_time.append(re.findall('(\d.\d晚)',i)) df['游玩时间'] = np.array(play_time) df
优化版: