Python数据分析与Pandas教程

数据分析的旅途中,经常会遇到各种挑战,比如数据缺失、异常值处理等。本文将带了解如何使用Python和Pandas库来解决这些问题,让能够独立探索世界,发现新知。如果一直在关注这个系列,那么这篇文章将为提供一双跑鞋,帮助开始奔跑。

通过本教程的学习,将掌握使用Python进行数据分析的所有必要工具。将回顾基础知识,包括Python的安装设置、有用的库和数据结构,以及如何使用Pandas进行探索性分析。

在之前的系列文章中,已经下载并设置了Python环境,介绍了几个有用的库和数据结构,并开始了使用Pandas的探索性分析。如果还没有阅读之前的文章,请先阅读,然后再继续。

数据清洗的必要性

数据探索过程中,发现了一些需要解决的问题,这些问题在数据准备好进行模型构建之前需要被解决。这个过程通常被称为“数据清洗”。以下是已经知道的问题:

在年龄字段中,大约31%(891中的277)的值缺失。预计年龄将扮演重要角色,因此希望能够以某种方式估计这个值。

在查看分布时,发现票价似乎包含了极端值——一些票可能是免费提供的,或者包含了数据输入错误。另一方面,512美元听起来像是一个非常高的票价。

除了这些数值字段的问题,还应该查看非数值字段,即姓名、票号和舱位,看看它们是否包含任何有用信息。

检查数据集中的缺失值

让从舱位开始。第一眼看这个变量,印象是数据集中有太多的NaN值。因此,让检查数据集中的空值/NaN值的数量。

sum(df['Cabin'].isnull())

这个Pandas命令应该告诉缺失值的数量,因为isnull()如果值为null则返回1。输出是687——这是一个很多的缺失值。因此,需要删除这个变量。

接下来,让看看票号变量。票号看起来混合了数字和文本,似乎不包含任何信息,所以也将删除票号。

df = df.drop(['Ticket','Cabin'], axis=1)

如何使用Pandas的fillna填充年龄中的缺失值

填充年龄的缺失值有多种方法——最简单的是用平均值替换,可以通过以下代码完成:

meanAge = np.mean(df.Age) df.Age = df.Age.fillna(meanAge)

另一个极端是构建一个监督学习模型,根据其他变量预测年龄,然后使用年龄和其他变量预测生存。

由于本教程的目的是展示数据清洗的步骤,将采取一个介于这两个极端之间的方法。关键假设是姓名、性别和舱位等级中的称呼可以提供所需的信息,以在很大程度上填补缺失值。

步骤1:从姓名中提取称呼

让定义一个函数,该函数从以这种格式书写的姓名中提取称呼:Family_Name, Salutation. First Name。

def name_extract(word): return word.split(',')[1].split('.')[0].strip()

接下来,使用apply()函数将这个函数应用到整个列,并把结果转换为一个新的Pandas DataFrame df2:

df2 = pd.DataFrame({'Salutation':df['Name'].apply(name_extract)})

一旦有了称呼,让看看它们的分布。在合并DataFrame df2和DataFrame df后使用groupby:

df = pd.merge(df, df2, left_index = True, right_index = True) # merges on index temp1 = df.groupby('Salutation').PassengerId.count() print temp1

以下是输出结果:

称呼

Capt 1

Col 2

Don 1

Dr 7

Jonkheer 1

Lady 1

Major 2

Master 40

Miss 182

Mlle 2

Mme 1

Mr 517

Mrs 125

Ms 1

Rev 6

Sir 1

the Countess 1

dtype: int64

如所见,有4个主要的称呼——Mr, Mrs, Miss和Master——其他的数量较少。因此,将把所有剩余的称呼合并为一个称呼——Others。为了做到这一点,采取与提取称呼相同的方法——定义一个函数,将其应用到一个新列,将结果存储在一个新的Pandas DataFrame中,然后将其与旧的DataFrame合并:

def group_salutation(old_salutation): if old_salutation == 'Mr': return('Mr') else: if old_salutation == 'Mrs': return('Mrs') else: if old_salutation == 'Master': return('Master') else: if old_salutation == 'Miss': return('Miss') else: return('Others') df3 = pd.DataFrame({'New_Salutation':df['Salutation'].apply(group_salutation)}) df = pd.merge(df, df3, left_index = True, right_index = True) temp1 = df3.groupby('New_Salutation').count() temp1 df.boxplot(column='Age', by = 'New_Salutation')

以下是新称呼的分布和年龄变化的结果:

步骤2:创建一个简单的网格(舱位等级 x 性别)x 称呼

同样地,通过性别和舱位等级绘制年龄分布图显示了一个斜率:

因此,创建一个透视表,它提供了上述所有单元格的中位数值。接下来,定义一个函数,该函数返回这些单元格的值,并将其应用于填补年龄的缺失值:

table = df.pivot_table(values='Age', index=['New_Salutation'], columns=['Pclass', 'Sex'], aggfunc=np.median) # 定义函数返回此透视表的值 def fage(x): return table[x['Pclass']][x['Sex']][ x['New_Salutation']] # 替换缺失值 df['Age'].fillna(df[df['Age']. isnull()].apply(fage, axis=1), inplace=True)

这应该为提供了一个填补年龄缺失值的好方法。

接下来,让看看按舱位等级划分的票价分布:

正如预期的那样,票价的均值整齐地按照舱位等级排列。然而,有一些极端值。一个特别引人注目的数据点,一级舱位的票价512,这看起来像是一个可能的错误。同样,有多种方法可以填补这个数据——用一级舱位的均值/中位数替换,或者也可以用第二高的值替换,这个值更接近其他数据点。

沪ICP备2024098111号-1
上海秋旦网络科技中心:上海市奉贤区金大公路8218号1幢 联系电话:17898875485