我们拿到的数据通常是不干净的,所谓的不干净,就是数据中有缺失值,有一些异常点等,需要经过一定的处理才能继续做后面的分析或建模,所以拿到数据的第一步是进行数据清洗,本章我们将学习缺失值、重复值、字符串和数据转换等操作,将数据清洗成可以分析或建模的亚子
我们拿到的数据经常会有很多缺失值,比如我们可以看到Cabin列存在NaN,那其他列还有没有缺失值,这些缺失值要怎么处理呢
请查看每个特征缺失值个数
方法一:
Train_data.info()
我们可以看到每列应该有891个数据,可以看到Age,Cabin,Embarked列存在缺失值
方法二:
Train_data.isnull().sum() #可以统计出每列缺失的值
(1)处理缺失值一般有几种思路
–删除,补全
(2) 请尝试对Age列的数据的缺失值进行处理
(3) 请尝试使用不同的方法直接对整张表的缺失值进行处理
法一:(不推荐)
Train_data[Train_data['Age']==np.NAN]=0 # 将缺失值置为0
Train_data.head(5)
法二:使用dropna和fillna(常用)
dropna函数参数:
(1)axis参数:默认情况为行,axis=1表示列
(2)how参数–可取值any或all,表示全为缺失去除和存在缺失去除
fillna函数参数:
(1)value:填充的值
(2)method:填充方法,如果没有参数,默认是ffill (向前填充)。 method=bfill 表示向后填充
(3)axis:需要填充的轴,默认axis=0,竖直方向填充
(4)inplace:修改被调用的对象
Train_data[Train_data.duplicated()]
我们对特征进行一下观察,可以把特征大概分为两大类:
数值型特征:Survived ,Pclass, Age ,SibSp, Parch, Fare,其中Survived, Pclass为离散型数值特征,Age,SibSp, Parch, Fare为连续型数值特征
文本型特征:Name, Sex, Cabin,Embarked, Ticket,其中Sex, Cabin, Embarked, Ticket为类别型文本特征,
数值型特征一般可以直接用于模型的训练,但有时候为了模型的稳定性及鲁棒性会对连续变量进行离散化。文本型特征往往需要转换成数值型特征才能用于建模分析
(1) 将连续变量Age平均分箱成5个年龄段,并分别用类别变量12345表示
df = pd.read_csv('test_clear.csv')
df['AgeBand'] = pd.cut(df['Age'], 5,labels = ['1','2','3','4','5'])
df.head()
(2) 将连续变量Age划分为[0,5) [5,15) [15,30) [30,50) [50,80)五个年龄段,并分别用类别变量12345表示
pd.cut(df['Age'],[0,5,15,30,50,80],labels=['1','2','3','4','5'])
df['AgeBand'] = pd.cut(df['Age'], 5,labels = ['1','2','3','4','5'],,right=False)
df.head()
# 其中right=False,表示区间右边是开的
(3) 将连续变量Age按10% 30% 50 70% 90%五个年龄段,并用分类变量12345表示
df['AgeBand'] = pd.qcut(df['Age'],[0,0.1,0.3,0.5,0.7,0.9,1],labels = ['1','2','3','4','5'],duplicates='drop')
df.head()
(1) 查看文本变量名及种类
方法一: value_counts
df['Embarked'].value_counts()
#方法二: unique
(2) 将文本变量Sex, Cabin ,Embarked用数值变量12345表示
#方法一: replace
df['Sex_num']=df['Sex'].replace(['male','female'],[1,2])
df.head()
df['Embarked_nums']=df['Embarked'].replace(['S','C','Q'],[1,2,3])
df.head()
df['Sex_num']=df['Sex'].map({'male':1,'female':2}) #map里面用字典表示
df.head()
#方法三: 使用sklearn.preprocessing的LabelEncoder (类别编号)
注:容易在导sklearn包出错的话,参考这个:
[https://blog.csdn.net/YZW_CSDN_/article/details/90480175?utm_medium=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-1.channel_param&depth_1-utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-1.channel_param]
from sklearn.preprocessing import LabelEncoder
for feat in ['Cabin','Ticket']:
lb1=LabelEncoder()
label_dict=dict(zip(df[feat].unique(),range(df[feat].nunique())))
df[feat+"_labelEncode"]=df[feat].map(label_dict)
df[feat + "_labelEncode"] = lb1.fit_transform(df[feat].astype(str))
df.head()
(3) 将文本变量Sex, Cabin, Embarked用one-hot编码表示
for feat in ["Age","Embarked"]:
x=pd.get_dummies(df[feat],prefix=feat)
df=pd.concat([df,x],axis=1)
df.head()
df['Title']=df.Name.str.extract('([A-Za-z]+)\.', expand=False)
df.head()
df[['Name','Title']]
([A-Za-z]+).
为了提取Mr,可以看到Mr前面有空格,且从大写字母开始再到小写字母 。
所以该正则表达式也是类似:先空了一格,从大写字母A-Z中匹配,再从小写字母a-z中匹配, 到 .(点)这里结束。
\表示转义,在正则表达式中点(.)表示:匹配除换行符 \n 之外的任何单字符。若要直接使用则需要加上转义符号
关于正则表达式可参考:
https://blog.csdn.net/m0_46352099/article/details/107787199