动手学数据分析之数据清洗及特征处理
开始之前,导入numpy、pandas包和数据
#加载所需的库
import numpy as np
import pandas as pd
from matplotlib import pyplot as plt
#加载数据train.csv
data=pd.read_csv('train.csv',header=0,encoding='utf-8')
data.head(10).append(data.tail(10))
2.1数据清洗简述
我们拿到的数据通常是不干净的,所谓的不干净,就是数据中有缺失值,有一些异常点等,需要经过一定的处理才能继续做后面的分析或建模,所以拿到数据的第一步是进行数据清洗,本章我们将学习缺失值、重复值、字符串和数据转换等操作,将数据清洗成可以分析或建模的样子。
2.1.1 观察缺失值
# 1.观察缺失值
## 方法一
data.info()
## 方法二
data.isnull().sum()
# 2.查看Age, Cabin, Embarked列的数据
data[['Age','Cabin','Embarked']]
data.loc[:][['Age','Cabin','Embarked']]
2.1.2 对缺失值进行处理
# 1、处理缺失值的一般思路:
#提醒:可使用的函数有--->dropna函数与fillna函数
data.dropna(inplace=False) # 丢弃缺失值
data.fillna(0,inplace=False) # 填充缺失值
data.isnull().sum()
# 2.利用索引填充
data[data['Age'].isnull()] = 0 # 给‘Age’列填充
data['Age'].fillna(0,inplace=False)
2.1.3重复值观察与处理
# 1.请查看数据中的重复值
data[data.duplicated()]
# 2.对重复值进行处理
data1 = data.drop_duplicates()
# 3.清洗结束保存数据
data1.to_csv('new_data.csv',index=False)
2.2 特征观察与处理
我们对特征进行一下观察,可以把特征大概分为两大类:
数值型特征 :Survived ,Pclass, Age ,SibSp, Parch, Fare,其中Survived, Pclass为离散型数值特征,Age,SibSp, Parch, Fare为连续型数值特征
文本型特征 : Name, Sex, Cabin,Embarked, Ticket,其中Sex, Cabin, Embarked, Ticket为类别型文本特征数.
值型特征一般可以直接用于模型的训练,但有时候为了模型的稳定性及鲁棒性会对连续变量进行离散化。文本型特征往往需要转换成数值型特征才能用于建模分析。
2.2.1 、对年龄进行分箱(离散化)处理
将数据分开操作,把连续型数据处理成离散型数据,文本型转换为数值型特征
# 1.分箱操作(对年龄离散化处理)
data['ageband']=pd.cut(data['Age'],5,labels=[1,2,3,4,5]) # 均分
#将连续变量Age划分为(0,5] (5,15] (15,30] (30,50] (50,80]五个年龄段,并分别用类别变量12345表示
data['AgeBand'] = pd.cut(data['Age'],[-1,5,15,30,50,81],labels = [1,2,3,4,5])
# 2.对文本变量进行转换
#方法一: replace
data['Sex_num']=data['Sex'].replace(['male','female'],[1,2])
#方法二: map
data['Sex_num1']=data['Sex'].map({"male":1,"female":2})
for feat in ['Cabin', 'Ticket']:
# 使用dict()函数将zip对象转换为字典,类似字典形式。zip生成格式类型[('Amo', 18), ('Paul', 19), ('Jason', 20), ('Seven', 21)]
label_dict = dict(zip(df[feat].unique(), range(df[feat].nunique()))) # zip() 函数用于将可迭代的对象作为参数,将对象中对应的元素打包成一个个元组
df[feat + "_labelEncode"] = df[feat].map(label_dict) #使用map函数,将字典里的键值代替键名
#方法三: 使用sklearn.preprocessing的LabelEncoder
from sklearn.preprocessing import LabelEncoder
for feat in ['Cabin', 'Ticket']:
lbl = LabelEncoder() # 实例化
data[feat + "_labelEncode"] = lbl.fit_transform(data[feat].astype(str)) #调用
df.head()
# 查看数据
data['Sex_num'].describe()
# 3.将类别文本转换为one-hot编码
#方法一: OneHotEncoder
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(data[feat], prefix=feat) # prefix为前缀
data = pd.concat([data, x], axis=1) # 将生成的onehot与原列表拼接
#df[feat] = pd.get_dummies(df[feat], prefix=feat)
#方法二:使用sklearn.preprocessing的OneHotEncoder
from sklearn.preprocessing import OneHotEncoder
for feat in ["Age", "Embarked"]:
lbl = OneHotEncoder(handle_unknown='ignore') # 实例化
lbl.fit_transform(data[feat].toarray()) #调用
2.2.2、 从纯文本Name特征里提取出Titles的特征(所谓的Titles就是Mr,Miss,Mrs等)
data['Title'] =data['Name']str.extract('([A-Za-z]+)\.', expand=False) # 正则化
2.2.3、根据箱线图处理异常值。
def outliers_proc(data, col_name, scale=3):
def box_plot_outliers(data_ser, box_scale):
iqr = box_scale * (data_ser.quantile(0.75) - data_ser.quantile(0.25))
val_low = data_ser.quantile(0.25) - iqr
val_up = data_ser.quantile(0.75) + iqr
rule_low = (data_ser < val_low)
rule_up = (data_ser > val_up)
return (rule_low, rule_up), (val_low, val_up)
data_n = data.copy()
data_series = data_n[col_name]
rule, value = box_plot_outliers(data_series, box_scale=scale)
index = np.arange(data_series.shape[0])[rule[0] | rule[1]]
data_n = data_n.drop(index)
data_n.reset_index(drop=True, inplace=True)
index_low = np.arange(data_series.shape[0])[rule[0]]
outliers = data_series.iloc[index_low]
index_up = np.arange(data_series.shape[0])[rule[1]]
outliers = data_series.iloc[index_up]
fig, ax = plt.subplots(1, 2, figsize=(10, 7))
sns.set(font='Times New Roman',font_scale=1.5)
sns.boxplot(y=data[col_name], data=data, palette="Set1", ax=ax[0])
sns.boxplot(y=data_n[col_name], data=data_n, palette="Set1", ax=ax[1])
plt.savefig("boxplot.svg",dpi=300)
return data_n
# 处理price的异常值
trainData = outliers_proc(trainData,'price', scale=3)