数据清洗及特征处理

数据清洗及特征处理

导入numpy、pandas包和数据

#加载所需的库
import numpy as np
import pandas as pd
#加载数据train.csv
df = pd.read_csv('train.csv')
df.head(3)

在这里插入图片描述

数据清洗概述

我们拿到的数据通常是不干净的,所谓的不干净,就是数据中有缺失值和异常点等,需要经过一定的处理才能继续做后面的分析或建模,所以拿到数据的第一步是进行数据清洗,本次我们将学习缺失值、重复值、字符串和数据转换等操作,清洗数据为后续的数据分析和建模做准备。

1. 缺失值观察与处理

1.1 缺失值观察

有很多方法可以查看缺失值:

方法1

df.info()

数据清洗及特征处理_第1张图片
通过观察,可以发现 Age, Cabin, Embarked 都存在缺失值。

方法2

df.isnull().sum()

数据清洗及特征处理_第2张图片

1.2 对缺失值进行处理

将缺失值赋值为0是一种常见操作,有以下几种尝试:

尝试1

df[df['Age']==None]=0
df.isnull().sum()

数据清洗及特征处理_第3张图片
发现 Age 缺失值无变化,说明这种方法无效。

尝试2

df[df['Age'].isnull()] = 0
df.isnull().sum()

数据清洗及特征处理_第4张图片
Age 缺失值个数为0,说明该方法有效。

尝试3

df[df['Age'] == np.nan] = 0
df.isnull().sum()

数据清洗及特征处理_第5张图片
发现 Age 缺失值无变化,说明这种方法无效。

总结:数值列读取数据后,缺失值的数据类型为float64所以用None和np.nan可能索引不到,最好用.isnull()进行索引。

使用 dropna 丢弃缺失值

DataFrame.dropna(axis=0, how=‘any’, thresh=None, subset=None, inplace=False)

Parameters:

axis:{0 or ‘index’, 1 or ‘columns’}, default 0

确定丢弃包含缺失值的行还是列

  • 0是丢弃包含缺失值的行
  • 1是丢弃包含缺失值的列

how:{‘any’, ‘all’}, default ‘any’

  • ‘any’ : 如果有一个缺失值,就丢弃所在行或列
  • ‘all’ : 只有某一行或某一列都为缺失值,才丢弃

inplace:bool, default False

如果为True,丢弃缺失值操作将原地进行,并返回 None。

Returns:DataFrame or None

如果 inplace 为 False,返回丢弃了缺失值的 DataFrame,否则返回None。

丢弃数据集中的缺失值,只要某行存在缺失值,就丢弃该行

df.dropna().info()

数据清洗及特征处理_第6张图片
观察发现,最后只有183条可用数据,证明这种做法很浪费数据。

使用 fillna 填充缺失值

DataFrame.fillna(value=None, method=None, axis=None, inplace=False, limit=None, downcast=None)

Parameters:

value:scalar, dict, Series, or DataFrame

用来填充缺失值的值,可以是标量、字典、Series 或 DataFrame。

method:{‘backfill’, ‘bfill’, ‘pad’, ‘ffill’, None}, default None

  • ffill:使用缺失值前面一个有效值去填充;
  • bfill:使用缺失值后面一个有效值去填充;

axis:{0 or ‘index’, 1 or ‘columns’}

按行或列方向填充缺失值

inplacebool, default False

是否原地执行操作

limitint, default None

对于连续的缺失值被最多填充个数,缺省值是无个数限制

Returns:DataFrame or None

如果 inplace 为 False,返回填充了缺失值的 DataFrame,否则返回None

将数据集中的缺失值都用0填充

df.fillna(0).info()

数据清洗及特征处理_第7张图片
填充之后,数据集中没有缺失值,数据条数也没有减少。

2. 重复值观察与处理

2.1 查看数据中的重复值

df[df.duplicated()]

在这里插入图片描述
原始数据里没有重复值。

2.2 丢弃重复值

df = df.drop_duplicates()

2.3 保存清洗过的数据

df.to_csv('test_clear.csv')

3. 特征观察与处理

我们对特征进行一下观察,可以把特征大概分为两大类:
数值型特征:Survived ,Pclass, Age ,SibSp, Parch, Fare,其中Survived, Pclass为离散型数值特征,Age,SibSp, Parch, Fare为连续型数值特征
文本型特征:Name, Sex, Cabin,Embarked, Ticket,其中Sex, Cabin, Embarked, Ticket为类别型文本特征。

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

3.1 对年龄进行分箱(离散化)处理

3.1.1 将连续变量Age平均分箱成5个年龄段,并分别用类别变量12345表示

df['AgeBand'] = pd.cut(df['Age'], 5,labels = [1,2,3,4,5])
df.head()

数据清洗及特征处理_第8张图片

3.1.2 将连续变量Age划分为(0,5] (5,15] (15,30] (30,50] (50,80]五个年龄段,并分别用类别变量12345表示

df['AgeBand'] = pd.cut(df['Age'],[0,5,15,30,50,80],labels = [1,2,3,4,5])
df.head(3)

数据清洗及特征处理_第9张图片

3.1.3 #将连续变量Age按20% 40% 60% 80% 五个年龄段,并用分类变量12345表示

df['AgeBand'] = pd.qcut(df['Age'],[0,0.2,0.4,0.6,0.8,1],labels = [1,2,3,4,5])
df.head()

在这里插入图片描述

3.2 对文本变量进行转换

3.2.1 查看文本变量名及种类

方法1:value_counts

df['Sex'].value_counts()

在这里插入图片描述

方法2:unique

df['Sex'].unique()

在这里插入图片描述

df['Sex'].nunique()

在这里插入图片描述

3.2.2 将文本变量Sex, Cabin ,Embarked用数值变量12345表示

方法1:replace

df['Sex_num'] = df['Sex'].replace(['male','female'],[1,2])
df.head()

数据清洗及特征处理_第10张图片

方法2:map

for feat in ['Cabin', 'Ticket']: 
    label_dict = dict(zip(df[feat].unique(), range(df[feat].nunique())))
    df[feat + "_labelEncode"] = df[feat].map(label_dict)

df.head()

数据清洗及特征处理_第11张图片

df['Cabin_labelEncode'].value_counts()

数据清洗及特征处理_第12张图片

方法3:使用sklearn.preprocessing的LabelEncoder

from sklearn.preprocessing import LabelEncoder
for feat in ['Cabin', 'Ticket']:
    lbl = LabelEncoder()  
    df[feat + "_labelEncode"] = lbl.fit_transform(df[feat].astype(str))

df.head()

数据清洗及特征处理_第13张图片

df['Cabin_labelEncode'].value_counts()

数据清洗及特征处理_第14张图片
可以发现,采用 map 方法与采用 LabelEncoder 方法的编码结果还是有区别的,这是因为不同的方法给相同的文本变量赋予了不同的数值。

3.2.3 将文本变量Sex,Embarked用one-hot编码表示

方法1 get_dummies

for feat in ["Sex", "Embarked"]:
    x = pd.get_dummies(df[feat], prefix=feat)
    df = pd.concat([df, x], axis=1)
    
df.head()

数据清洗及特征处理_第15张图片

方法2:OneHotEncoder

from sklearn.preprocessing import OneHotEncoder
onehot_model = OneHotEncoder(handle_unknown='ignore')
onehot_features= ["Sex", "Embarked"]
onehot_model.fit(df[onehot_features].astype(str))
after_onehot_features = onehot_model.get_feature_names(onehot_features)
data_train_onehot = pd.DataFrame(onehot_model.transform(df[onehot_features]).toarray(),columns=after_onehot_features)
df = df.join(data_train_onehot)
df.head()

数据清洗及特征处理_第16张图片
注意,使用 get_dummies 得到的独热编码的数据类型为 uint8,
使用 OneHotEncoder 得到的独热编码的数据类型为 float64。

3.3 从纯文本Name特征里提取出Titles的特征(所谓的Titles就是Mr,Miss,Mrs等)

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

数据清洗及特征处理_第17张图片

参考资料

  • Datawhale 开源文档:https://github.com/datawhalechina/hands-on-data-analysis
  • https://gitee.com/datawhalechina/hands-on-data-analysis/tree/master

感谢Datawhale对开源学习的贡献!

你可能感兴趣的:(python,数据分析)