数据分析入门系列教程-数据清洗

简介: 从今天开始,我们再一起来学习数据分析,共同进步!首先先来进行一个数据清洗的实战,使用比较经典的数据集,泰坦尼克号生存预测数据。数据集下载地址https://github.com/zhouwei713/DataAnalyse/tree/master/Titanic_dataset

导入数据


import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
df = pd.read_csv('titanic_data.csv')
df

数据集信息如下:

image.png

各字段含义

pclass:船票等级

sibsp:一同登船的兄弟姐妹或配偶数量

parch:一同登船的父母或子女数量

ticket:船票号码

fare:船票价格

cabin:船舱

embarked:登船地点


数据整体查看


拿到数据之后,我们先整体查看下数据信息

df.describe()


image.png

还有些列是非数值的,所以没有展示。

这里得到的各项指标,我们先保存不动,在后面处理缺失值时会有用到。


处理缺失值


首先查看缺失值

df.isnull().sum()
>>>
pclass         1
survived       1
name           1
sex            1
age          264
sibsp          1
parch          1
ticket         1
fare           2
cabin       1015
embarked       3
dtype: int64

可以看到,缺失值比较多的是 cabin 和 age


年龄处理

查看缺失占比

print('缺失占比 %.2f%%' %((df['age'].isnull().sum()/df.shape[0])*100))
>>>
缺失占比 20.15%

下面查看下年龄的分布情况

age = df['age'].hist(bins=15, color='teal', alpha=0.6)
age.set(xlabel='age')
plt.xlim(-10,85)
plt.show()


image.png

从图中我们可以看出,整体数据是向左偏的,即大多数数据是小于平均值的,故而我们可以采用中位数来填补空值,而不是平均数。

从上面的 describe 函数的输出值也可以看出,平均值是 29.88,中位数是 28,显然中位数更加接近于大部分数据所在的区域。

使用中位数填充空缺的年龄值

data = df.copy()
data['age'].fillna(df['age'].median(skipna=True), inplace=True)


仓位处理

查看缺失百分比

print('缺失百分比 %.2f%%' %((df['cabin'].isnull().sum()/df.shape[0])*100))
>>>
缺失百分比 77.48%

由于仓位信息已经缺失了大部分,所以这里选择直接删除处理

data.drop(columns=['cabin'], inplace=True)


登船地点处理

我们先来查看下登船地点这列数据的形式

print(df['embarked'].value_counts())
sns.countplot(x='embarked', data=df, palette='Set2')
plt.show()
>>>
S    914
C    270
Q    123
Name: embarked, dtype: int64


image.png

可以看到,登船地点总共包含三类数据,S、C 和 Q,他们出现的次数分别为 914、270 和 123。

又因为该列数据总共缺失 3 个,缺失率很低,使用众数来填充这三个缺失值应该是没问题的。

使用众数填充

data['embarked'].fillna(df['embarked'].value_counts().idxmax(), inplace=True)


其他缺失值处理

对于其他列,只是缺失了一到两个,可以采用众数的方式来填充缺失值,也可以选择直接删除掉缺失的部分,不影响整体数据分布

data.dropna(axis=0, how='any', inplace=True)

最后,再查看确认下是否不存在缺失值了

data.isnull().sum()
>>>
pclass      0
survived    0
name        0
sex         0
age         0
sibsp       0
parch       0
ticket      0
fare        0
embarked    0
dtype: int64


其他特征列处理


对于 sibsp 和 parch 两列,我们可以抽象成是否是独自登船,这样就能够把两列合并为一列,并用 0,1 来表示是否独自登船。

我们新增一列 alone,把两列都是 0 的数据添加到新列中并设置为 0,把两列相加不为 0 的数据添加到新列中,并设置数值为 1。那么原来的两列就可以删除了。

data['alone']=np.where((data["sibsp"]+data["parch"])>0, 0, 1)
data.drop('sibsp', axis=1, inplace=True)
data.drop('parch', axis=1, inplace=True)
data.head()


image.png

对于 embarked 和 sex 这两列,都是字符串类型的数据,需要转化为数字才能被算法模型分析处理。

这里可以采用独热编码的方式,来转换数据

data =pd.get_dummies(data, columns=["embarked","sex"])
data.head()


image.png

独热编码(one-hot encoding),是一种常用的数据转换方式,对于每一个特征,如果它有 m 个可能值,那么经过独热编码后,就变成了 m 个二元特征,这些特征互斥,每次只有一个激活。

对于 name 和 ticket 两列,由于他们的存在,对于我们的数据分析没有任何意义,往往会直接删除掉这样无意义的数据

data.drop('name', axis=1, inplace=True)
data.drop('ticket', axis=1, inplace=True)

至此,我们就把一份原始的数据,处理成了比较标准的,易于数据分析的数据。


透视表分析


在处理数据之后,我们还可以使用透视表,整体分析下数据

这里主要查看下各个特征(船票等级,性别,仓位等)对于存活率的影响

注意数据集 df 与 data 的区别


性别透视表

首先来看下,不同性别,存活率的情况

sex_sur_table = pd.pivot_table(df, index=['sex'], values='survived')
print(sex_sur_table)
>>>
        survived
sex             
female  0.727468
male    0.190985

女性存活率是远远高于男性的,ladies first。

船票等级与存活率

pclass_sur_table = pd.pivot_table(df, index=['sex'], columns=['pclass'], values='survived')
print(pclass_sur_table)
>>>
pclass       1.0       2.0       3.0
sex                                 
female  0.965278  0.886792  0.490741
male    0.340782  0.146199  0.152130

可以看到,一等船票的女性存活率是非常高的,同时船票等级越高,无论男女,存活率都越高

不同年龄存活率

将年龄离散化处理

data['age_cut'] = pd.cut(data['age'], [0, 18, 90])
data['sex'] = df['sex']
print(data.head())
>>>
   pclass  survived      age      fare  alone  embarked_C  embarked_Q  \
0     1.0       1.0  29.0000  211.3375      1           0           0   
1     1.0       1.0   0.9167  151.5500      0           0           0   
2     1.0       0.0   2.0000  151.5500      0           0           0   
3     1.0       0.0  30.0000  151.5500      0           0           0   
4     1.0       0.0  25.0000  151.5500      0           0           0      embarked_S  sex_female  sex_male   age_cut     sex  
0           1           1         0  (18, 90]  female  
1           1           0         1   (0, 18]    male  
2           1           1         0   (0, 18]  female  
3           1           0         1  (18, 90]    male  
4           1           1         0  (18, 90]  female

年龄段与存活率

age_cut_sur_table = pd.pivot_table(data, index=['sex'], columns=['pclass', 'age_cut'], values='survived')
print(age_cut_sur_table)
>>>
pclass        1.0                 2.0                 3.0          
age_cut   (0, 18]  (18, 90]   (0, 18]  (18, 90]   (0, 18]  (18, 90]
sex                                                                
female   0.923077  0.969466  0.952381  0.870588  0.534483  0.474684
male     0.750000  0.321637  0.523810  0.093333  0.208333  0.142857

当然,透视表还有很多强大的功能,你可以试着探索更多。


数据清洗的重要性


要知道,一个好的数据分析师必定是一名数据清洗高手。在数据分析的过程中,数据清洗是最占用时间与精力的步骤。数据质量的高低,直接影响我们最后分析的结果,千万马虎不得。


数据质量的准则

那么既然数据清洗这么重要,我需要把原始数据处理到什么程度,才算是合格的待分析数据呢?如下我总结了一些业界的标准,可以供你参考。

  • 完整性:数据集中是否存在空值,统计的字段是否完善。
  • 全面性:某列数据,是否能够全面的反应真实的情况,是否只包含一部分情况。
  • 合法性:数据的类型,内容,大小等是否合理。比如:是否有年龄超过 150 的,是否有成绩超过 1 万的,数据单位是否统一等等。
  • 唯一性:数据是否存在重复记录。

在进行数据清洗的时候,一定要先耐心的观察数据,充分的理解每列数据的意义,从真实的情况出发分析数据是否有真实的含义,再根据生活工作中的经验,来逐一处理数据。

我们再用一个小例子来理解下

姓名 身高 体重 年龄 年龄
张飞 180
500
500
关羽 181 100 28
28
刘备 1.78 160 30K
30k
赵云 175 140 23
23
曹操 180 150 37
37
赵云 175
140
23
曹操




把数据转化成 Pandas 数据结构

mydata = pd.read_csv('mydata.csv', index_col='name')
print(mydata)
>>>
      height  weight  age age.1
name                           
张飞    180.00     NaN  500   500
关羽    181.00   100.0   28    28
刘备      1.78   160.0  30K   30K
赵云    175.00   140.0   23    23
曹操    180.00   150.0   37    37
赵云    175.00   140.0   23    23
典韦       NaN     NaN  NaN   NaN


完整性

查看缺失值

mydata1 = mydata.copy()  # copy
mydata1.isnull().sum()  # 查看总体缺失值
>>>
height    1
weight    2
age       1
age.1     1
dtype: int64

一般是处理空值,空行等

mydata1['weight'].fillna(mydata1['weight'].mean(), inplace=True)  # 使用平均值填充
#mydata1['height'].fillna(mydata['height'].value_counts().index[0], inplace=True)  # 使用众数填充
mydata1.dropna(how='any', inplace=True)  # 删除空行

一定要先执行空值填充,再执行删除空行的代码,否则含有空值的行都会被删除。

全面性

刘备的身高是“米”的单位,我们需要转换为“厘米”

mydata1.loc[mydata1['height']<100, 'height'] = mydata1[mydata1['height']<100]['height']*100


合理性

张飞的年龄是 500,显然不合理,需要处理。因为张飞是三弟,年龄需要比刘备和关羽小,就设置为 27 吧

mydata1.loc['张飞', 'age'] = 27

同时刘备的年龄还存在一个 K 字符,需要去掉

mydata1['age'].replace({r'[K]': ''}, regex=True, inplace=True)


唯一性

数据中还存在重复的行和列,也需要删除,保证数据的唯一性

mydata1.drop_duplicates(inplace=True)  # 删除重复行
mydata1.drop('age.1', axis=1, inplace=True)  # 删除不需要的列

最终我们的数据为

print(mydata1)
>>>
      height  weight age
name                    
张飞     180.0   138.0  27
关羽     181.0   100.0  28
刘备     178.0   160.0  30
赵云     175.0   140.0  23
曹操     180.0   150.0  37


总结


本节我们共同完成了一个数据清洗的实战和一个练习小例子。对于缺失值,需要根据其缺失的百分比及数据分布情况,来决定如何填充缺失值。对于一些非数字类型的数据,可以选择独热编码等方式转换数据。还总结了数据清洗的准则,只要你遵循这些准则来处理数据,那么得到的数据基本就是“好”的数据了。

image.png

练习题


对于本节的例子,你还有哪些观点,对于缺失值的填充,是否还有其他的方式呢?对于 pclass,sex 等数据的缺失值,还可以怎么处理呢,欢迎留言讨论啊

相关文章
|
2月前
|
数据采集 存储 数据可视化
Python数据分析从入门到实践
Python数据分析从入门到实践
|
7天前
|
数据采集 数据可视化 数据挖掘
SciPy在数据分析中的应用:从数据清洗到可视化
【4月更文挑战第17天】# SciPy在数据分析中的应用:从数据清洗到可视化。文章探讨了SciPy在数据清洗(使用NumPy处理缺失值和异常值)、数据分析(描述性统计和模型拟合)以及数据可视化(结合Matplotlib和Seaborn进行图表绘制)中的作用。SciPy与其他Python库结合,为完整的数据分析流程提供了强大支持。
|
18天前
|
机器学习/深度学习 数据可视化 数据挖掘
利用Python进行数据分析与可视化:从入门到精通
本文将介绍如何使用Python语言进行数据分析与可视化,从基础概念到高级技巧一应俱全。通过学习本文,读者将掌握Python在数据处理、分析和可视化方面的核心技能,为实际项目应用打下坚实基础。
|
2月前
|
机器学习/深度学习 数据可视化 数据挖掘
Python数据分析:从入门到实践
Python数据分析:从入门到实践
|
2月前
|
数据采集 数据挖掘 大数据
Python 数据分析中的数据清洗技巧与实践
【2月更文挑战第1天】数据分析是当下热门的技术领域之一,而数据清洗作为数据分析过程中至关重要的一环,往往被人们忽视。本文将深入探讨在 Python 环境下进行数据清洗的关键技巧与实际操作,帮助读者提升数据分析的效率与准确性。
|
3月前
|
存储 数据挖掘 索引
Python 教程之 Pandas(14)—— 使用 Pandas 进行数据分析
Python 教程之 Pandas(14)—— 使用 Pandas 进行数据分析
26 0
Python 教程之 Pandas(14)—— 使用 Pandas 进行数据分析
|
4月前
|
存储 机器学习/深度学习 数据挖掘
提升数据分析效率:Amazon S3 Express One Zone数据湖实战教程
提升数据分析效率:Amazon S3 Express One Zone数据湖实战教程
75 1
|
4月前
|
存储 数据挖掘 Python
借助 PyPDF2 库把数据分析系列教程文章制作成了PDF电子书,欢迎来领取!
借助 PyPDF2 库把数据分析系列教程文章制作成了PDF电子书,欢迎来领取!
|
4月前
|
数据采集 算法 数据可视化
数据分析入门系列教程-EM实战-划分LOL英雄
数据分析入门系列教程-EM实战-划分LOL英雄
|
4月前
|
机器学习/深度学习 算法 数据挖掘
数据分析入门系列教程-股票走势预测分析
数据分析入门系列教程-股票走势预测分析
数据分析入门系列教程-股票走势预测分析