数据清洗
数据清洗的概念
类比定义
数据分析过程 做菜过程
明确需求 明确做什么菜
收集采集 去菜市场买菜
数据清洗 洗菜切菜配菜
数据分析 炒菜
数据报告+数据可视化 拍照发朋友圈吃菜
专业定义
数据清洗是从记录表,表格,数据库中检查,纠正或删除损坏或不准确记录的过程
专业名称
脏数据
没有经过处理自身含有一定问题的数据(缺失,异常,重复...)
干净数据
经过处理完全符合规范要求的数据
常用方法
1.读取外部数据
read_csv read_excel read_sql read_html
2.数据概览
index columns head tail shape describe 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'],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 = '-(x*?)\d' df.loc[df.目的地.isnull(),'目的地'] = [re.findall('-(.*?)\d',i) for i in df.loc[df.目的地.isnull(),'路线名'].values]
作业讲解之缺失值处理
针对缺失数据有几种处理方法
1.占比过小可以直接删除
2.利用均值,统一值直接填充
3.根据不同的情况采用不同的计算公式填充
常用的四个方法
isnull
notnull
fillna
dropna
保留几位小数
round(数据,保留几位)
# 计算缺失数据占比 df.isnull().sum()/df.shape[0] # 我们自己规定占比小于0.1%可以直接删除 # 筛选出所有价格缺失的数据 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()
新增两个列
分别是酒店类型、酒店评分、游玩时间
text = '(.{2}型)' res=[] for i in df['酒店']: res1 = re.findall(text,i) res.append(res1) df['酒店类型'] = res text1 = '(.{3}分)' res=[] for i in df['酒店']: res1 = re.findall(text1,i) res.append(res1) df['酒店评分'] = res text2 = '(.{1}晚)' res=[] for i in df['房间']: res1 = re.findall(text2,i) res.append(res1) df['游玩时间'] = res