数据清洗
-
数据清洗的概念
-
数据清洗实战案例

详细
-
数据清洗的概念
# 我们可以把数据分析的过程比作制作一道菜 数据分析 ——> 做菜 明确需求 ——> 明确要做什么菜 采集数据 ——> 去菜市场等买菜 数据清洗 ——> 洗菜、切菜、配菜 数据分析 ——> 炒菜 撰写报告+可视化 ——> 装盘拍照发朋友圈+给别人吃

准确定义
# 数据清洗 从记录表(文本文件),表格(Excel文件),数据库(db)中检测、纠正、删除损坏以及不准确记录的过程。 # 脏数据 未经处理的自身含有一定问题的数据(缺失、异常、重复...等)。 # 干净数据 经过处理的完全符合分析必要的规范的数据。

数据清洗的常用流程
1.读取外部数据: 根据数据来源选择 read_csv read_excel read_sql read_html 2.数据概览: 掌握现有数据的大概情况 index columns head tail shape describe info: 该属性返回个数、是否含有缺失数据以及类型 dtypes 3.初步处理 移除首尾空格 .strip()、大小写转换等 4.重复值处理 duplicated() 查看是否含有重复数据 drop_duplicates() 删除重复数据 5.缺失值处理 删除缺失值 dropna()、填充缺失值 fillna() 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()


列字段处理
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]

重复值处理
4、查找重复数据
df.duplicated()

5、了解重复数据的大概情况
df[df.duplicated()]

6、重复数据一般可以直接删除
df.drop_duplicates(inplace=True)

7、确认是否成功删除
df.shape

8、这里要注意一点,删除数据后,行索引不会自动重置
(1) 获取行索引值
df.index

(2) 按照当前行数修改行索引值
df.index = range(0, df.shape[0])
(3) 查看修改完的行索引值
df.tail()

异常值处理
1、利用快速统计大致筛选出可能有异常数据的字段,如优惠力度大于原价的数据
df.describe()

2、利用公式判断可能出现异常的数据
价格的标准分数 = (价格-价格的平均值)/价格的标准差
这里引入一个概念,标准分数—standard score
用公式表示为:z=(x-μ)/σ;其中z为标准分数;x为某一具体分数,μ为平均数,σ为标准差。
Z值的量代表着原始分数和母体平均值之间的距离,是以标准差为单位计算。
在原始分数低于平均值时Z则为负数,反之则为正数。
一般情况下,标准分数的绝对值大于3则为极端值,即异常数据。
sd = (df['价格']-df['价格'].mean()) / df['价格'].std() # 判断sd的绝对值是否大于3 df[(sd > 3)|(sd < -3)] df[abs(sd) > 3]

# 查找优惠力度大于原价的数据(推荐下列方式) df[df['节省'] > df['价格']]

3、删除异常数据
(1) 先拼接,再删除(也可以按照结果依次删除)
横向合并: pd.merge()
纵向合并: pd.concat()
res = pd.concat( [df[df['节省'] > df['价格']], df[abs(sd) > 3]] )

(2) 获取要删除的行数据的行索引
del_index = res.index

(3) 根据行索引删除数据
df.drop(index=del_index, inplace=True)

(4) 重置行索引
df.index = range(0, df.shape[0])

出发地缺失值处理
1、查找具有缺失值的列字段名称以及数目
df.isnull()
df.isnull().sum()


2、利用布尔值索引筛选出缺失出发地的数据
df[df.出发地.isnull()]

3、获取缺失出发地的数据的路线数据
df.loc[df.出发地.isnull(), '路线名'].values

4、利用字符串切割提取出发地替换出发地这一列的的缺失数据
df.loc[df.出发地.isnull(), '出发地'] = [i.split('-')[0] for i in df.loc[df.出发地.isnull(), '出发地'].values] """ 1.操作数据的列字段需要使用loc方法 不支持直接使用[] 2.缺失值处理 (1)采用数学公式依据其他数据填充 (2)其他单元格中可能含有缺失值数据 (3)缺失值占比特别小的情况下有时可以删除 """

目的地缺失值处理
1、利用布尔值索引筛选出缺失目的地的数据
df[df.目的地.isnull()]

2、获取缺失目的地的数据的路线数据
df.loc[df.目的地.isnull(), '路线名'].values

3、由于需要的字符串不在首尾,更适合利用正则筛选目的地
import re reg_exp = '-(.*?)\d' # 正则案例 resTest = re.findall(reg_exp, '深圳-秦皇岛3天2晚 | 入住大连黄金山大酒店 + 南方航空/东海往返机票')

# 具体操作 df.loc[df.目的地.isnull(), '目的地'] = [re.findall(reg_exp, i) for i in df.loc[df.目的地.isnull(), '路线名'].values]

价格/节省缺失值处理
1、筛选出所有缺失价格的数据
df[df['价格'].isnull()]

2、利用均值填充缺失数据
avgP = df['价格'].mean() # 四舍五入 p = round(avgP, 1) df['价格'].fillna(p, 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;
-
作业
1、添加三列,酒店类型、酒店评分、游玩时间。
# 思路 1.筛选酒店字段 hotelTypes = [] for hotelType in df['酒店'].values: # 使用空格匹配 hotelTypes.append(re.findall(' (.*?) ', hotelType)) # 创建新的列—酒店类型 df['酒店类型'] = hotelTypes
# dataframe类型自带匹配正则的方法
df['酒店类型'] = df['酒店'].str.extract(' (.*?) ') 2.筛选酒店评分 hotelScores = [] for hotelScore in df['酒店'].values: # 使用空格匹配 hotelScores.append(re.findall('(\d\.\d)分', hotelScore)[0]) .需要取消转义 # 创建新的列—酒店评分 df['酒店评分'] = hotelScores 3.筛选游玩时间 days = [] for routeName in df['路线名'].values: # 使用晚字前的天数匹配 days.append(re.findall('(\d.*?晚)', routeName)[0]) \d+天\d+晚 # 创建新的列—游玩时间 df['游玩时间'] = days


浙公网安备 33010602011771号