3.3 数据清洗与合并
数据预处理包含了数据清洗 (data cleansing) 与特征工程 (feature engineering) ,本节主要介绍的是数据清洗部份,主要目的是将原始数据转换成整洁的、组织合理的形式以供后续的特征工程使用。而数据清洗的工作内容很多,举例来说:
- 基础运算 (basic) - 选择、过滤、删除重复项。
- 取样 (Sampling) - 基于绝对、相对或是概率。
- 数据划分 (Data Partitioning) - 将数据集划分为训练、验证、测试数据集。
- 装箱 (Binning) - 这是用于减少微小观测误差影响的技术,常见的应用如直方图 (Histograms)。
- 转换 (Transformations) - 如标准化,标准化,缩放,旋转。
- 数据替换 (Data Replacement) - 剪切、拆分、合并。
- 插补 (Imputation) - 使用统计算法替换缺失的观察值。
- 加权 (Weighting) - 属性加权。
本节将会介绍基础运算中的过滤、找出缺失值、删除重复项以及数据替换中的剪切、拆分、合并。
3.3.1 泰坦尼克号竞赛 - 数据过滤
以 Kaggle 上著名的泰坦尼克号竞赛的中所提供的数据集来练习,这是一个数据科学有名的竞赛网站,而这个泰坦尼克号竞赛是透过网站所提供的数据来预测,哪些人的生存几率高。透过 info() 函数可以得知这个数据集有 891 笔数据,共有 12 个栏位。
titanic 数据集说明
| 栏位 | 说明 |
|---|---|
| survival | 是否存活 |
| pclass | 船票等级 |
| sex | 性别 |
| Age | 年龄 |
| sibsp | 船上兄弟姐妹的人数 |
| parch | 船上父母、儿女的人数 |
| ticket | 票号 |
| fare | 船运票价 |
| cabin | 船舱号码 |
| embarked | 上船的港口 |
import pandas as pd
import numpy as np
dataDir = './data/titanicTrain.csv'
df = pd.read_csv(dataDir)
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
接着过滤男性,且年龄在20岁以下的乘客,过滤结果共有 102 位。
df[(df['Age']<=20) & (df['Sex']=='male')]
输出结果为:
PassengerId Survived Pclass Name Sex Age SibSp Parch Ticket Fare Cabin Embarked
7 8 0 3 Palsson, Master. Gosta Leonard male 2.0 3 1 349909 21.0750 NaN S
12 13 0 3 Saundercock, Mr. William Henry male 20.0 0 0 A/5. 2151 8.0500 NaN S
16 17 0 3 Rice, Master. Eugene male 2.0 4 1 382652 29.1250 NaN Q
27 28 0 1 Fortune, Mr. Charles Alexander male 19.0 3 2 19950 263.0000 C23 C25 C27 S
50 51 0 3 Panula, Master. Juha Niilo male 7.0 4 1 3101295 39.6875 NaN S
... ... ... ... ... ... ... ... ... ... ... ... ...
844 845 0 3 Culumovic, Mr. Jeso male 17.0 0 0 315090 8.6625 NaN S
850 851 0 3 Andersson, Master. Sigvard Harald Elias male 4.0 4 2 347082 31.2750 NaN S
869 870 1 3 Johnson, Master. Harold Theodor male 4.0 1 1 347742 11.1333 NaN S
876 877 0 3 Gustafsson, Mr. Alfred Ossian male 20.0 0 0 7534 9.8458 NaN S
877 878 0 3 Petroff, Mr. Nedelio male 19.0 0 0 349212 7.8958 NaN S
102 rows × 12 columns
在上述的数据中,可以发现舱位 (Cabin) 栏位很多是没有填写的 (NaN),如果分析者认为这个栏位对于在灾难发生时是没有影响的,可以选择删除,但如果这个栏位是有影响的,那在清洗过程,必须让所有的值是有意义的,所以我们必须先找出缺失值,然后替换成有意义的值。首先我们先找出在所有数据中有几个舱位,利用 Pandas 的聚合函数 groupby() 可以找出所有的数据并排序,发现共有 147 个舱位
# 依序列出所有数据
df[['Cabin']].groupby(['Cabin'],sort=True).count()
输出结果为:
Cabin
A10
A14
A16
A19
A20
...
F33
F38
F4
G6
T
147 rows × 0 columns
我们可以用 duplicated() 来找出重复行,第一次出现的为 False,如果再出现一次就视为重复,所以就设定为 True,以下以 'Sex' 栏位来进行重复行检验,可以发现它的重复次数为 889,因为第一次出现的 0 与 1 并不会被记录
len(df[df['Sex'].duplicated()])
输出结果为:
889