【学习笔记】Python进行数据清洗

写在前面的话

最近看了一个up主讲基本数据清洗操作,觉得非常好,链接如下:

【Python 数据清洗】用Python给数据洗澡澡~ |数据分析|数据清洗|数据预处理|_哔哩哔哩_bilibili

 评论区也有原数据集和相关代码的链接(不是广告),下面就浅浅记一下自己的学习笔记。除此之外,up主的缺失值处理是直接用均值进行替代,个人觉得不是很严谨,所以替换成了随机森林算法填补缺失值。

需要注意的是,正常的顺序应该是先进行缺失值处理,再进行文本提取、时间处理等操作,但是因为我用随机森林的时候需要用文本提取来创造新变量,所以把两者顺序调转了一下。


目录

1. 读取数据

2. 数据探索与描述

3. 数据简单处理

4. 文本字符串/时间格式序列处理

5. 缺失值/异常值处理

6. 总结(思维导图)


1. 读取数据

import pandas as pd
df = pd.read_csv(".\qunar_freetrip.csv",index_col = 0)
df.head()

【学习笔记】Python进行数据清洗_第1张图片

2. 数据探索与描述

df.info()
df.describe()
df.shape


3. 数据简单处理

# 通过该命令发现列名有空格
col = df.columns.values

#进行清洗
df.columns = [x.strip() for x in col]
df.columns

# 重复值
df.duplicated() #返回布尔型数据,告诉重复值的位置
df[df.duplicated()] #返回重复数值
df.duplicated().sum()  #返回重复值数量
df.drop_duplicates(inplace = True) # 删除重复值,inplace=True表示在原数据集上进行操作


# 需要注意的是去重之后需要索引重置
df.reset_index()

4. 文本字符串/时间格式序列处理

# 正则提取酒店评分等信息
# ''里面是规则;()里面是提取内容
import re

df['酒店评分'] = df['酒店'].str.extract('(\d\.\d)分/5分',expand = False)
df['酒店等级'] = df['酒店'].str.extract(' (.+) ', expand = False)
df['time_start'] = [x.split('-')[0].strip() for x in df['去程时间']]
df['time_end'] = [x.split('-')[1].strip() for x in df['去程时间']]
df['天数'] = df['房间'].str.extract('\d+间(\d+)晚', expand = False)
df['航空公司'] = [re.findall(r'[\u4e00-\u9fff]+',x)[0] for x in df['去程航司']]


# 时间格式处理
from datetime import datetime as dt
df['start'] = [dt.strptime(x,'%H:%M') for x in df['time_start']]
df['end'] = [dt.strptime(y,'%H:%M') for y in df['time_end']]
df['minute'] = [round(x.seconds/60,0) for x in (df['end'] - df['start'])]
df = df.drop(df[['end','start']],axis = 1)

5. 缺失值/异常值处理

#(1)异常值
## (a)异常值检测
### motivation: 对缺失值进行处理的时候需要考虑去掉异常值
df.describe().T

### 发现最大值比较离谱,现在对异常值进行定义,在三倍标准差之外的是异常值
sta = (df['价格']-df['价格'].mean())/df['价格'].std()

### 找出价格异常值
df[sta.abs()>3]  #此时需要和业务进行了解,这个异常值的原因,是输入错误还是

### 找出节省异常值
df[df['价格']3]]).index #获取异常值的index
df.drop(deindex, inplace = True)  #
df = df.reset_index()


# 缺失值
## (a)缺失值检测
### 看缺失值一共有多少
df.isnull().sum()

### 查看具体确实数值,挨个看缺失值的模式
df[df.出发地.isnull()] #比如出发地,可以看到路线名中包含了出发地和目的地
df.loc[df.出发地.isnull(), '出发地'] = [str(x).split('-')[0] for x in df.loc[df.出发地.isnull(), '路线名']]
df.loc[df.目的地.isnull(), '目的地'] = [str(x).split('-')[1][:2] for x in df.loc[df.目的地.isnull(), '路线名']]


## (b) 缺失值处理
null_index = df[df['价格'].isnull()].index #记录一下空缺值索引,这样后面可以进行对比

### 方法一:直接删除缺失值
df1 = df.copy()  #因为要讨论多种方法,所以复制一下原表
df1.dropna(axis=0,how='any',inplace=True) # inplace是否原地替换
df1.shape


### 方法二:取均值
# 思考:直接填充均值是否太随便了,能不能用【出发地,目的地,去程航司,时间,去程方式】进行预测
df2 = df.copy()
df2[df2['价格'].isnull()]
df2['价格'].fillna(round(df2['价格'].mean(),0), inplace = True)
df2['节省'].fillna(round(df2['节省'].mean(),0), inplace = True)


### 方法三:随机森林进行填补

null_index = df[df['价格'].isnull()].index #记录一下空缺值索引,等会可以看一下拟合结果是否离谱

df3 = df.copy()
#生成虚拟变量
dummy = pd.get_dummies(df3[['出发地','目的地','去程方式','航空公司']], prefix=None, prefix_sep='_')
dummy['key']=[x for x in range(len(dummy))]
#获取数值变量
df_sub = df3[['价格','minute']]
df_sub['key']=[x for x in range(len(df_sub))]
#合并
df_merge = pd.merge(df_sub,dummy,on=['key','key'])

from sklearn.ensemble import RandomForestRegressor
# 随机模型预测
# 分成已知和未知价格数据
known_price = df_merge[df_merge['价格'].notnull()].values
unknown_price = df_merge[df_merge['价格'].isnull()].values

y = known_price[:,0]
X = known_price[:,1:]

#进行拟合
model = RandomForestRegressor(random_state=0, n_estimators=2000,n_jobs=-1)
model.fit(X,y)

#预测
predictedPrice = model.predict(unknown_price[:, 1:])
df3.loc[(df3['价格'].isnull()),'价格'] = predictedPrice

# 对比方法2和3
df2['key'] = [x for x in range(len(df2))]
df3['key'] = [x for x in range(len(df3))]
comparison = pd.merge(df2[['key','价格']],df3[['key','价格']],on=['key','key'])
comparison.iloc[null_index,:]

这里的数值处理推荐这个博客:【Python数据分析基础】: 数据缺失值处理 - 码农教程

以及推荐一个jupyter快捷键博客:https://blog.csdn.net/baidu_26137595/article/details/124063900

6. 总结(思维导图)

【学习笔记】Python进行数据清洗_第2张图片

你可能感兴趣的:(python,pandas,机器学习)