动手学数据分析(2)--数据清洗及特征处理

数据清洗及特征处理

1 数据清洗

1.1 加载数据

import numpy as np
import pandas as pd
df=pd.read_csv('train.csv')

1.2 缺失值的观察和处理

# 查看每个特征缺失值的个数
# 显示的是不含缺失值的个数
df.count()
df.info()

# 显示的是缺失值的个数
df.isnull().sum()

# 查看‘Age’,‘Cabin’,‘Embarked’列的数据
# 法一
df[['Age','Cabin','Embarked']]

# 法二
df.loc[:,['Age','Cabin','Embarked']].head(3)

# 法三
print(df.iloc[:,[5,10,11]].head(3))

处理缺失值的思路

1.删除缺失值

2.填充缺失值

#处理‘Age’列数据的缺失值
#令‘Age’列的缺失值为0
#法一
df[df['Age']==None]=0

#法二
df[df['Age].isnull()]=0

#法三
df[df['Age']==np.nan]=0

思考:检索空缺值用np.nan,None以及.isnull()哪个更好?

回答:数值列读取数据后,空缺值的数据类型为float64,所以None一般索引不到,比较的时候最好用np.nan。

#直接对整张表的缺失值进行处理
#删除含缺失值的列
df.dropna()

#用0填充缺失值
df.fillna(0)

思考:dropna和fillna()有哪些参数,分别如何使用?

回答:


 

参数名称(drop)说明
axisaxis=0删除行,axis=1删除列
how

any表示行或列有一个缺失值就清除 

all表示要是整行都是缺失值才清除

thresh

只接受一个int值

表示保留n个非空值的行或列

subset

接受一个集合(可以使列表、元组、数组)

表示哪些列或行必须不能有空值,处在这些列或行的空值的行或列将被清除

inplace

接受bool

如果为True,返回None并且直接对原数组进行缺失值的清理。

如果是False,那么只返回一个copy

参数说明(fillna)说明
axis

axis=0,表示选择行

axis=1,表示选择列(默认)

value用来表示代替缺失值的值
method

取值为backfill(bfill)表示使用缺失值的下一个非缺失值来填补缺失值

取值为pad(ffil)表示使用缺失值的上一个非缺失值来填补缺失值

limit

接受int

表示在每行或每列填补缺失值个数上限,超过这个上限不再继续填补。

inplace

接受bool

如果为True,在原表上操作

如果是False,那么只返回一个copy

1.3 重复值的观察与处理

#查看数据中的重复值
df[df.duplicated()]

#删除数据中的重复值(不改变原本数值)
df=df.drop_duplicates()

#如果想要保留最后一行或全部删除,用keep设置参数
df=df.drop_duplicates(keep='last')
df=df.drop_duplicates(keep=False)

#同样可以设置subset方法,就可以指定哪些字段重复视为重复值
df.drop_duplicates(subset=['Age','Sex'])


1.4 将清洗数据保存

df.to_csv('test_clear.csv')

2.特征观察与处理

特征大概可以分为2类

数值型特征文本型特征

survived,pclass(离散型数值特征)

Age,SlibSp,Parch,Fare(连续型数值特征)

Name

Sex,Cabin,Embarked,Ticket(类别型文本特征)

数值型特征一般可以直接用于模型的训练,但有时为了模型的稳定性以及鲁棒性会连续变量进行离散化。文本型特征往往需要转换成数值型特征才能用于建模分析。

2.1 分箱(离散化处理)

2.1.1 分箱操作是什么?

我们在建立模型前,一般需要对特征变量进行离散化,特征离散化后,模型会更稳定,降低模型过拟合的风险。尤其是采用 logsitic 建立评分卡模型时,必须对连续变量进行离散化。而特征离散化处理通常采用的就是分箱法,数据分箱(也称为离散分箱或分段)是一种数据预处理技术,用于减少次要观察误差的影响,提高泛化性。

数据分箱又分为有监督分箱和无监督分箱,是否使用标签进行离散化(分箱)决定了有监督还是无监督的离散化方法。

2.1.2 分箱操作实例

#平均分箱5个年龄段,并用类别变量1,2,3,4,5
df['AgeBand']=pd.cut(df['Age'],5,labels=[1,2,3,4,5])

#划分为(0,5],(5,15]...5个年龄段。
df['AgeBand']=pd.cut(df['Age'],[0,5,15,30,50,80],5,labels=[1,2,3,4,5])

#按10%,30%,...五个年龄段
df['AgeBand'] = pd.qcut(df['Age'],[0,0.1,0.3,0.5,0.7,0.9],labels = [1,2,3,4,5])

2.2 对文本变量进行转换

2.2.1 查看文本变量名以种类

#查看文本变量名
#方法一 value_counts
df['Sex'].value_counts()

#方法二: unique
df['Sex'].unique()

#查看文本种类数量
df['Sex'].nunique()


2.2.2 用数值变量表示文本变量

#将类别文本转换为12345
#方法1 replace
df['Sex_num']=df['Sex'].replace(['male','female'],[1,2])

#方法2 map
df['Sex_num']=df['Sex'].map({'male':1,'female':2})


#方法三: 使用sklearn.preprocessing的LabelEncoder
#标准化标签,将标签值统一转换成range(标签值个数-1)范围内
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))

2.2.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(df[feat], prefix=feat)
    df = pd.concat([df, x], axis=1)
    #df[feat] = pd.get_dummies(df[feat], prefix=feat)

2.2.4从纯文本Name特征里提取出Title的特征

#为了提取Mr,可以看到Mr前面有空格,且从大写字母开始再到小写字母 。
#所以该正则表达式也是类似:先空了一格,从大写字母A-Z中匹配,再从小写字母a-z中匹配, 到 .(点)这##里结束。
#\表示转义,在正则表达式中点(.)表示:匹配除换行符 \n 之外的任何单字符。若要直接使用则需要加上转#义符号

#expand= 布尔值,默认为真。 如果为真,则返回每个捕获组有一列的数据框。如果为假,如果有一个捕获  #组,则返回序列/索引;如果有捕获组,则返回数据框。

df['Title'] = df.Name.str.extract(' ([A-Za-z]+)\.', expand=False)

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值