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

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

从今天开始,我们再一起来学习数据分析,共同进步!

首先先来进行一个数据清洗的实战,使用比较经典的数据集,泰坦尼克号生存预测数据。

数据集下载地址

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

数据集信息如下:

各字段含义

pclass:船票等级

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

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

ticket:船票号码

fare:船票价格

cabin:船舱

embarked:登船地点

据整体查看

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

df.describe()


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

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

处理缺失值

首先查看缺失值

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()


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

从上面的 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


可以看到,登船地点总共包含三类数据,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()


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

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

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


独热编码(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

总结

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

练习题

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

相关文章
|
9天前
|
SQL 数据挖掘 Python
R中单细胞RNA-seq数据分析教程 (1)
R中单细胞RNA-seq数据分析教程 (1)
28 5
R中单细胞RNA-seq数据分析教程 (1)
|
1月前
|
数据可视化 数据挖掘 大数据
Python 数据分析入门:从零开始处理数据集
Python 数据分析入门:从零开始处理数据集
|
1月前
|
数据采集 数据可视化 数据挖掘
使用Python进行数据分析:从入门到实践
使用Python进行数据分析:从入门到实践
50 2
|
24天前
|
数据采集 机器学习/深度学习 数据可视化
深入浅出:用Python进行数据分析的入门指南
【10月更文挑战第21天】 在信息爆炸的时代,掌握数据分析技能就像拥有一把钥匙,能够解锁隐藏在庞大数据集背后的秘密。本文将引导你通过Python语言,学习如何从零开始进行数据分析。我们将一起探索数据的收集、处理、分析和可视化等步骤,并最终学会如何利用数据讲故事。无论你是编程新手还是希望提升数据分析能力的专业人士,这篇文章都将为你提供一条清晰的学习路径。
|
1月前
|
机器学习/深度学习 数据可视化 数据挖掘
使用Python进行数据分析的入门指南
【9月更文挑战第33天】本文旨在为初学者提供一个关于使用Python进行数据分析的全面概述。我们将从基本的安装和设置开始,逐步介绍数据处理、数据可视化以及机器学习的基本概念和应用。文章将通过实际代码示例来展示如何使用Python及其相关库来解决常见的数据分析问题。
|
1月前
|
数据挖掘 索引 Python
Python数据分析篇--NumPy--入门
Python数据分析篇--NumPy--入门
33 0
|
1月前
|
数据采集 数据可视化 数据挖掘
Python 数据分析实战:使用 Pandas 进行数据清洗与可视化
【10月更文挑战第3天】Python 数据分析实战:使用 Pandas 进行数据清洗与可视化
91 0
|
1月前
|
机器学习/深度学习 数据采集 数据可视化
Python中的简单数据分析:入门指南
【10月更文挑战第2天】Python中的简单数据分析:入门指南
33 0
|
3月前
|
数据采集 数据可视化 数据挖掘
数据分析大神养成记:Python+Pandas+Matplotlib助你飞跃!
在数字化时代,数据分析至关重要,而Python凭借其强大的数据处理能力和丰富的库支持,已成为该领域的首选工具。Python作为基石,提供简洁语法和全面功能,适用于从数据预处理到高级分析的各种任务。Pandas库则像是神兵利器,其DataFrame结构让表格型数据的处理变得简单高效,支持数据的增删改查及复杂变换。配合Matplotlib这一数据可视化的魔法棒,能以直观图表展现数据分析结果。掌握这三大神器,你也能成为数据分析领域的高手!
79 2
|
3月前
|
机器学习/深度学习 数据采集 数据可视化
基于爬虫和机器学习的招聘数据分析与可视化系统,python django框架,前端bootstrap,机器学习有八种带有可视化大屏和后台
本文介绍了一个基于Python Django框架和Bootstrap前端技术,集成了机器学习算法和数据可视化的招聘数据分析与可视化系统,该系统通过爬虫技术获取职位信息,并使用多种机器学习模型进行薪资预测、职位匹配和趋势分析,提供了一个直观的可视化大屏和后台管理系统,以优化招聘策略并提升决策质量。
179 4