目录
从纯文本Name特征提取出Titles的特征(即Mr、Miss、Mrs等)
本文是学习开源项目‘hands-on data analysis’之后的个人总结,总结内容为数据清洗及特征处理可执行的操作,如下
项目链接:https://github.com/datawhalechina/hands-on-data-analysis
数据集下载:https://www.kaggle.com/c/titanic/overview
数据清洗及特征处理
一、缺失值处理
-
查看缺失值:
DataFrame.isnull()、pd.isnull(DataFrame)、np.any(DataFrame.isnull())==True、Series.isnull() -
查看每列缺失值个数:
DataFrame.info()、DataFrame.isnull().sum() -
处理缺失值——删除/填充值:
用dropna()删除缺失数据(传入参数inplace=True则会原地修改数据):DataFrame.dropna()
可选参数:axis、how、thresh、subset、inplace
官方文档:https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.dropna.html
用fillna()填充缺失数据(传入参数inplace=True则会原地修改数据):
DataFrame.fillna(value=0) 用指定值给缺失数据填入值,
value可以是标量、字典(索引:元素)、Series、DataFrame
可选参数:value、method、axis、limit、inplace、downcast
官方文档:https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.fillna.html
赋值法填充缺失数据(这种方法会对DataFrame本身进行修改):
DataFrame[DataFrame['column名'].isnull()] = 0
‘.isnull()’可更换为‘==None’或‘==np.nan’;
末尾的填充值0,也可以是均值等
【注意】此法除会对DataFrame本身进行修改外,还会将指定列中为NA的数据所在行的值都填充为0,不推荐;若费用使用可修改为:DataFrame.loc[DataFrame['column名'].isnull(),'column名'] = 0
【补充】缺失值的几种情况(用‘==’比较) python中用None表示缺失值,该元素除了等于自身外,与其他任何元素不相等 numpy中用np.nan表示缺失值,该元素除了不和其他任何元素相等外,和自身的比较结果也返回False
二、重复值处理
-
查看重复值:
DataFrame.duplicated():默认判断全部列,返回布尔型Series,表示各行是否与前面行重复 DataFrame[DataFrame.duplicated()]:返回所有的重复的数据行 DataFrame.duplicated(['column名', ['column名']]):指定部分列进行重复项判断,
默认除第一次出现外,将重复项标记为True,即keep='first';
传入keep='last'则保留最后一个,其余标记为True
-
移除重复数据:
DataFrame.drop_duplicates():默认判断全部列,返回DataFrame,重复的行被删除 DataFrame.drop_duplicates(['column名']):指定某列进行重复项判断,
该列重复行将被删除,返回一个DataFrame, 默认返回第一次出现重复项的行
传入参数inplace=True则会原地修改数据
三、保存清洗的数据
DataFrame.to_csv('文件名.csv'):常保存数据为csv格式,也可保存为其他格式 |
四、特征观察与处理
对特征进行观察前,首先需要将特征分类:
数值型特征:连续型数值特征,如年龄;离散型数值特征,如分类数据-物品等级 |
文本型特征:普通文本型特征,如姓名;类别型文本特征,如分类数据-性别 |
不同类型特征的处理:
数值型特征一般可直接用于模型的训练,但有时为了模型的稳定性及鲁棒性会对连续变量离散化 |
文本型特征,特别是类别型文本特征往往需要转换成数值型特征才能用于建模分析 |
可用的处理方法:
-
离散化/面元划分/分箱操作:
本质:将连续型数值特征(连续数据)离散化 分箱:对于一组连续值,对其切分成若干段,每一段将其看做一个类别 pd.cut('要分箱的一维数组', bins, labels=None,precision=3):等距分组或按指定bins分组
传入参数right=False,设置bins区间为左闭右开,即上组限不在内;默认为左开右闭
bins可为整数:等距分组的组数;标量组成的序列:分组的组限值;
IntervalIndex:定义要使用的具体的分箱
labels指定返回的bins的标签,即类别名
precision指定bins保留的小数位,默认为3
官方文档:https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.cut.html
pd.qcut('要分箱的Series/一维数组', q, labels=None,precision=3):按分位数分组
传入参数right=False,设置bins区间为左闭右开,即上组限不在内;默认为左开右闭
q可为分位数:如4代表按四分位数cut分箱,10代表按十分位数cut分箱;
分位数组成的列表:如[0, 0.1, 0.4, 0.8, 1]
labels指定返回的bins的标签,即类别名;默认为None
precision指定bins保留的小数位,默认为3
官方文档:https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.qcut.html
通常,可将bins后的结果添加到DataFrame的列,即DataFrame['新column名']=pd.cut('要分箱的1-D数组',bins)
DataFrame['新column名'].codes:查看原'要分箱的1-D数组'中各元素属于哪个组(组标号从0开始)
DataFrame['新column名'].categories:返回分组相关的信息-哪几个组、区间开闭情况、类型
pd.value_counts(DataFrame['新column名']):返回每个组的元素个数
-
对文本变量进行转换
查看文本变量名及种类:
DataFrame['column名'].value_counts():返回某列的数据值的种类,及每类的频数、及数据类型dtype
DataFrame['column名'].unique():返回某列的数据值种类及dtype组成的array
DataFrame['column名'].nunique():返回某列的数据值种类的个数
将文本变量数据值的种类转换为数值,如12345:
法1:用replace替换值:
DataFrame['column名'].replace(待替换的值,用何值替换)
DataFrame.replace(待替换的值,用何值替换)
Series.replace([待替换的值1, 待替换的值2],[替换值1,替换值2])
DataFrame.replace({待替换的值1:替换值1, 待替换的值2:替换值2})
法2:用map映射替换值:
DataFrame['column名'].map({'原值1': '替换值1', '原值2': '替换值2'})
官方文档:https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.Series.map.html
法3:用sklearn.preprocessing的LabelEncoder:(待整理,此处仅贴出代码及结果)
from sklearn.preprocessing import LabelEncoder for feat in ['Cabin', 'Ticket']: lbl = LabelEncoder() label_dict = dict(zip(df[feat].unique(), range(df[feat].nunique()))) df[feat + "_labelEncode"] = df[feat].map(label_dict) df[feat + "_labelEncode"] = lbl.fit_transform(df[feat].astype(str)) df.head()
Out 输出:
将类别文本转换为one-hot编码:即将某列的类别数据值的分类添加到原DataFrame的列中
法1:用pd.get_dummies()把类别特征转为指示变量/哑变量
pd.get_dummies(data, prefix=None, prefix_sep='_', drop_first=False)
官方文档:https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.get_dummies.html
这里是转换为one-hot编码,注意与转换为哑变量的区别:
参考:one-hot编码和哑变量(dummy)编码、one-hot与哑变量(dummy variable)的区别
for feat in ["Age", "Embarked"]: # x = pd.get_dummies(df["Age"] // 6) # x = pd.get_dummies(pd.cut(df['Age'],5)) x = pd.get_dummies(df[feat], prefix=feat) df = pd.concat([df, x], axis=1) # 将原DataFrame与新生成的合并连接 # df[feat] = pd.get_dummies(df[feat], prefix=feat) df.head()
Out 输出:
法2:用sklearn.preprocessing的OneHotEncoder
参照:数据预处理:独热编码(One-Hot Encoding)和 LabelEncoder标签编码
-
从纯文本Name特征提取出Titles的特征(即Mr、Miss、Mrs等)
df['Title'] = df.Name.str.extract('([A-Za-z]+)\.', expand=False) df.head()
Out 输出:
关于Series.str.extrac()函数的官方文档:https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.Series.str.extract.html
这里也用到了正则表达式
五、保存最终清理好的数据
DataFrame.to_csv('文件名.csv'):常保存数据为csv格式,也可保存为其他格式 |
注意:建议实时保存自己清洗的数据成.csv文件