第二章:数据清洗及特征处理
1、数据清洗
在拿到数据之后先对数据进行检查,是否存在不干净数据,所谓的不干净,就是数据中有缺失值,有一些异常点等。数据清洗非常重要,将会影响后面的分析和建模。数据清洗涉及到缺失值、重复值、数据类型的转换等,下面将对这些问题进行逐步解决。
#加载相应的库和数据,train.csv(泰坦尼克号数据)
import numpy as np
import pandas as pd
df = pd.read_csv('train.csv',error_bad_lines=True) #error_bad_lines=True 这个参数是为了剔除有太多列的行,比如一共有3列,但有一行有4列数,这行将被剔除。默认是False,出现问题将不会返回DataFrame
- 缺失值处理
#第一种方法
df.info() #查看数据信息
#结果如下
'''
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 891 entries, 0 to 890
Data columns (total 12 columns):
# Column Non-Null Count Dtype
--- ------ -------------- -----
0 PassengerId 891 non-null int64
1 Survived 891 non-null int64
2 Pclass 891 non-null int64
3 Name 891 non-null object
4 Sex 891 non-null object
5 Age 714 non-null float64
6 SibSp 891 non-null int64
7 Parch 891 non-null int64
8 Ticket 891 non-null object
9 Fare 891 non-null float64
10 Cabin 204 non-null object
11 Embarked 889 non-null object
dtypes: float64(2), int64(5), object(5)
memory usage: 83.7+ KB
None
'''
#第二种方法
df.isnull().sum()
#运行结果
'''
PassengerId 0
Survived 0
Pclass 0
Name 0
Sex 0
Age 177
SibSp 0
Parch 0
Ticket 0
Fare 0
Cabin 687
Embarked 2
dtype: int64
'''
#仅查看某几列
df[['Age','Cabin','Fare']].isnull().sum()
#运行结果
'''
Age 177
Cabin 687
Fare 0
dtype: int64
'''
经过上述查看,“Age",“Cabin”,“Embarked”,这三列含有缺失值,下面将对缺失值进行相应的处理。
#将缺失值取0
df[df['Age']==None]=0
df[df['Age'].isnull()]=0
df[df["Age"] == np.nan]=0
df.fillna(0)
#整行删除
df.dropna()
fillna 函数将用指定的值(value)或方式(method)填充 NA/NaN 等空值缺失值。
DataFrame.fillna(value=None, method=None, axis=None, inplace=False, limit=None, downcast=None, kwargs)
value:用于填充的值,可以是数值、字典、Series 对象 或 DataFrame 对象。
method:当没有指定 value 参数时,可以该参数的内置方式填充缺失值,可选项有 {‘backfill’, ‘bfill’, ‘pad’, ‘ffill’, None},默认值为 None;backfill 和 bfill 用下一个非缺失值填充该缺失值,pad 和 ffill 用前一个非缺失值去填充该缺失值。该参数通常和 axis 一起使用Note,method 参数不能与 value 同时出现。
axis:指定填充维度,选项有 ‘index’ 或 ‘columns’,0 等同于 ‘index’ 表示行维度,1 等同于 ‘columns’ 表示列维度。
inplace:是否修改原对象的值,True 表示修改,默认是 False,表示创建一个副本,修改副本,原对象不变。
limit:指定填充的个数上限,默认为 None,即不限制。
dropnan:过滤缺失数据
DataFrame.dropna(axis=0, how=‘any’, thresh=None,subset=None, inplace=False)
axis{0 or ‘index’, 1 or ‘columns’}, default 0
how{‘any’, ‘all’}, default ‘any’
#删除表中全部为NaN的列
df.dropna(axis=1,how='all') #axis=0,删除行
#删除表中含有任何NaN的列
df.dropna(axis=1,how='any')
# 丢弃‘Age’和‘Sex’这两列中有缺失值的行 。可以指定列,进行检查。
data.dropna(axis=0,subset = ["Age", "Sex"]) # 丢弃‘Age’和‘Sex’这两列中有缺失值的行
【思考题】检索空缺值用np.nan要比用None好,这是为什么?
np.nan,None,NaN三种缺失值都会被替换为统一的NA符号,且不改变数据类型.
np.nan是一个float类型的数据 None是一个NoneType类型。
在ndarray中None显示为None 并且对象为object类型,如果进行计算 结果会报错。
- 重复值处理
#删除重复值
df.drop_duplicates()
2、特征观察与处理
- 分箱处理
#将连续变量Age平均分箱成5个年龄段,并分别用类别变量12345表示
df['AgeBand'] = pd.cut(df['Age'], 5,labels = ['1','2','3','4','5'])
#将连续变量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)
#将连续变量Age按10% 30% 50 70% 90%五个年龄段,并用分类变量12345表示
df['AgeBand'] = pd.qcut(df['Age'],[0,0.1,0.3,0.5,0.7,0.9],labels = ['1','2','3','4','5'])
df.head()
- 文本转换
#查看类别文本变量名及种类
#方法一: value_counts
df['Sex'].value_counts()
#方法二: unique
df['Sex'].unique()
#将类别文本转换为12345
#方法一: replace
df['Sex_num'] = df['Sex'].replace(['male','female'],[1,2])
#方法二: map
df['Sex_num'] = df['Sex'].map({'male': 1, 'female': 2})
#将类别文本转换为one-hot编码
#方法一: OneHotEncoder
for feat in ["Age", "Embarked"]:
x = pd.get_dummies(df[feat], prefix=feat)
df = pd.concat([df, x], axis=1)
#从纯文本Name特征里提取出Titles的特征(所谓的Titles就是Mr,Miss,Mrs等)
df['Title'] = df.Name.str.extract('([A-Za-z]+)\.', expand=False)
'''
根据正则表达式进行提取。
'([A-Za-z]+)\.':()具有优先权,匹配到之后只提取出括号内的值,'\.'是对'.'进行转义。[A-Za-z]匹配一切大小写字母。'+'表示1~+∞次。
'''