小丸子踏入python之路:python_day05(用Pandas处理泰坦尼克船员获救数据titanic_train.csv)

泰坦尼克船员获救数据:

    titanic_train.csv

用excel打开数据集。显示如下:

写在前边:

  为了方便以后运用numpy和pandas的库,分别造它们的别名np和pd.

import pandas as pd         #造pandas的别名为pd
import numpy as np          #造numpy的别名为np

 一、读取数据

import pandas as pd         #造pandas的别名为pd
import numpy as np          #造numpy的别名为np

#泰坦尼克号船员获救数据
titanic_survival = pd.read_csv("titanic_train.csv")
titanic_survival.head()     #head()无参数,默认返回数据的前5行

运行结果:

二、对数据进行处理

 1. 用 .isnull()来处理数据的缺失值

  其实数据都有缺失值,在进行数据处理的时候首先对缺失值要有一个详细的了解。

  下边将通过对列“age”列的处理来看一下缺失值的情况的。

  .isnull()可以返回缺失值的情况。若当前值缺失,返回true,否则返回false。

age = titanic_survival["Age"]
print(age.loc[0:10])                               #显示age数据的0——10行

#用.isnull()对缺失值进行处理。若当前的值为一个缺失值,则返回true,否则返回false
age_is_null = pd.isnull(age)
print(age_is_null)

#将age_is_null的值为true的留下来,把age_is_null值为false的过滤掉
age_null_true = age[age_is_null]
print(age_null_true)                               #打印所有的缺失值

age_null_count = len(age_null_true)                #打印缺失值的个数
print("age属性缺失值的个数: ",age_null_count)

运行结果:

2.缺失值的那点事 

2.1 当不对缺失值进行处理的时候会有什么后果呢?

  为什么要对缺失值进行处理?

  打比方:

     目标:现在想要求出船员的平均年龄。

         过程:则对“Age”这列数据进行操作。用sum()函数求出船员的年龄总和。用len()求出样本数据的长度,即船员的个数。

#目标:求船员的平均年龄
#过程:用sum()函数求出船员的年龄总和。用len()求出样本数据的长度,即船员的个数
mean_age = sum(titanic_survival["Age"])/len(titanic_survival["Age"])  #船员的平均年龄
print("平均年龄 = ",mean_age)                                          #打印平均年龄

  那么这样的操作是否能得到我们想要的结果呢?

 运行结果:

 

  这样的显示结果是因为原本的“Age”数据中存在缺失值,而缺失值会被标记为NaN,所以参与运算后平均年龄的返回结果为NaN

2.2 如何对缺失值未处理造成的后果进行调整呢?

   由2.1明显的看出缺失值的错在对数据的处理带来的后果,那么接下来,我们就用不同的方法对其进行解决。

2.2.1 直接过滤缺失值的办法。

  有第一节中,age_is_null的变量,我们得到了关于是否为缺失值的返回。

当其为缺失值的时候,age_is_null = True

但其不是缺失值的时候,age_is_null = False

#对上边缺失值导致结果出不来的情况进行一个处理。

#最简单的方法就是把有缺失值的直接去掉,只保留没有缺失值的,并进行运算。
good_ages = titanic_survival["Age"][age_is_null == False]     
                  #[age_is_null == False]若没有缺失值,则保留。(由此滤去缺失值)
#print(good_ages)
correct_mean_age = sum(good_ages) / len(good_ages)
print("平均年龄 = ",correct_mean_age)

运行结果:

2.2.2 直接用pandas中提供的mean()方法来处理

correct_mean_age = titanic_survival["Age"].mean()       #直接用Pandas中自带的mean()函数求平均
print("用mean()得到的平均年龄 = ",correct_mean_age)

运行结果:

2.2.3 注意

   其实直接滤去缺失值的样本并不是一个很好的方法,其实我们可以拿年龄的平均数、中位数、重数进行一个填充。

 3.求每类船舱对应的平均票价

3.1 用for循环的方式求出平均

  要求:船舱等级一共有[1,2,3]三种,分别对应不同的票价,所以每一级船舱都有自己的平均票价。求每级船舱的平均票价。

    过程:通过for循环对每一类船舱进去抽取,抽取出属于同一类船舱等级的船客的全部信息,再从每一个分类船客中抽出“Fare”(船票价格)这列数据,对其用,mean()函数求平均,再返回给每一类的类别。

#船舱等级一共有3种,求每一种船舱等级对应的平均票价
passenger_classes = [1,2,3]                    #船舱等级用list列出[1,2,3]
fares_by_class = {}                            #定义空的字典,用来存放船舱等级以及对应的平均票价
for this_class in passenger_classes:           #对每一类船舱进行循环
    pclass_rows = titanic_survival[titanic_survival["Pclass"] == this_class]          #当this_class = 1时,返回的是所有一等舱的船客的信息
                                                                                      #this_class = 2/3时同理
    pclass_fares = pclass_rows["Fare"]                          #再从每次取得的信息中,返回“Fare”(票价)这列的数据
    fare_for_class = pclass_fares.mean()                        #用.mean()对票价求平均
    fares_by_class[this_class] = fare_for_class                 #将对应的平均票价传给对应的船舱                
print("每类船舱对应的平均票价 = ", fares_by_class)

运行结果:

3.2 用pandas自带的函数.pivot_table()来统计船舱等级与平均票价的关系

   看了3.1后发现,我们的需求很简单,但是代码实现起来并不是很简便,那么有没有什么Pandas自带的方法来简便的完成这类数据统计的操作呢?答案当然是肯定的啦,不然我怎么会又开了3.2. 吼吼

.pivot_table() : 相当于一个数据透视表。

                         也相当于统计一个量与其他量之间关系的一个函数

.pivot_table()有三个参数:

           index:表示接下来要统计的信息是以谁为基准的,index就 = 谁

           values:表示用统计index与谁之间的关系,values就 = 谁

                   aggfunc:表示index与values之间的什么关系,aggfunc就 = 什么关系(不写的话,默认求均值)

#用.pivot_table来统计Pclass和Fare之间的关系
#三个参数:index:表示接下来要统计的信息是以谁为基准的,index就=谁(每个船舱等级对应的平均票价,所以index = Pclass船舱等级)
#        values:表示用统计Pclass与谁之间的关系,values就=谁(Pclass与票价之间的关系,values = Fare)
#        aggfunc:表示Pclass与Fare之间的什么关系,求的是船舱等级与票价的平均值之间的关系,所以aggfunc=np.mean()

passenger_classes = titanic_survival.pivot_table(index = "Pclass",values = "Fare",aggfunc = np.mean) print(passenger_classes)

运行结果:

 4.用.pivot_table()求每类船舱对应的平均存活率

#求每类船舱对应的存活率
#.pivot_table的三个参数:
#三个参数:index:表示接下来要统计的信息是以谁为基准的,index就=谁(每个船舱等级对应的平均存活率,所以index = Pclass船舱等级)
#        values:表示用统计Pclass与谁之间的关系,values就=谁(Pclass与存活率之间的关系,values = Survived)
#        aggfunc:表示Pclass与Survived之间的什么关系,求的是船舱等级的平均存活率的关系,所以aggfunc=np.mean()
passenger_survical = titanic_survival.pivot_table(index = "Pclass",values = "Survived",aggfunc = np.mean)
print(passenger_survical)

运行结果:

5.用.pivot_table()求每类船舱对应的平均年龄

#求每类船舱对应的平均年龄
#.pivot_table的三个参数:
#三个参数:index:表示接下来要统计的信息是以谁为基准的,index就=谁(每个船舱等级对应的平均年龄,所以index = Pclass船舱等级)
#        values:表示用统计Pclass与谁之间的关系,values就=谁(Pclass与年龄之间的关系,values = Age)
#        aggfunc:表示Pclass与Age之间的什么关系,求的是船舱等级的平均年龄的关系,所以aggfunc=np.mean()
passenger_age = titanic_survival.pivot_table(index = "Pclass",values = "Age",aggfunc = np.mean)
print(passenger_age)

运行结果:

6. 用.pivot_table()看一个量与其他两个量之间的关系

需求:想要看不同的登船地点(C,Q,S)的总的票价和总的获救人数。

过程:用.pivot_table()的话,对于index ,接下来要统计的东西是以登船地点为基准的,所以index = "Embarked"

                        对于values,要统计的是不同登船地点与票价和是否获救之间的关系,所以values = ["Fare","Survived" ]

                        对于aggfunc,要统计的是不同登船地点的总的票价和总的获救人数,所以aggfunc = np.sum

port_stats = titanic_survival.pivot_table(index = "Embarked",values = ["Fare","Survived"],aggfunc = np.sum)
print(port_stats)

运行结果:

7. 用.dropna()扔掉具有缺失值的行

#用.dropna扔掉具有缺失值的行
titanic_survival.head(7)
new_titanic_survival = titanic_survival.dropna(axis = 0,subset = ["Age","Sex"])
#看一些Age和Sex这两列有没有缺失值的,如果有,就把具有缺失值的这行数据扔掉。
titanic_survival.head(7)               
#new_titanic_survival.head(7)                 #分别把drop前后的前7行数据看一下吧

运行结果:dropna之前的数据 

注意:此打印的结果是不带print的打印方式,因为带有print的打印一行显示不完,看起来不够清楚。

dropna之后的数据

 

8. 用.loc()确定到每一个坐标上的数据

   数据中每一个具体的值都是由一个行号和列名唯一确定的,所以完全可以用行号和列名来返回这个位置上的值。

#如何取确定位置上的一个数据
row_index_83_age = titanic_survival.loc[83,"Age"]
row_index_766_pclass = titanic_survival.loc[766,"Pclass"]
print("第83行的age = ",row_index_83_age)
print("第766行的pclass = ",row_index_766_pclass)

运行结果:

9.用.sort_values()进行数据的重新排序,并用.reset_index()重置排序后的index值(即行号)。

  用.sort_values()对数据进行排序后,虽然行的顺序因为排序条件发生了变化,但是其行号却还保持着之前的样子,为了让排序后的数据的行号变成从0开始,依次增大,所以运用.reset_index()进行重置。

new_titanic_survival = titanic_survival.sort_values("Age",ascending = False)    #根据“Age”的大小逆序排列。
#print(new_titanic_survival[0:10])                                               #打印未进行.reset_index时的数据前10行
titanic_reindexed = new_titanic_survival.reset_index(drop = True)
#print(titanic_reindexed.loc[0:10])
new_titanic_survival[0:10]

titanic_reindexed.loc[0:10]

运行结果: 

注意:此打印的结果是不带print的打印方式,因为带有print的打印一行显示不完,看起来不够清楚。

 未进行.reset_index时的数据前10行

  

进行.reset_index后的数据前边10行

 10、apply(自定义函数名) 的功能

  我们知道pandas已经提供了很多个功能强大的函数,但是还是会有一些具体的操作没有办法直接用已经定义的函数来完成的,此时我们应该如何执行这些呢?

一方面,可以通过写代码慢慢的拼接出来。

另一方面,可以通过写apply()函数,而这个apply()函数就相当于我们可以进行一个自定义函数的操作。

         在apply()中传进来的是一个函数名,而传进来的函数可以是自己定义的函数,即将自己的操作定义成一个函数的形式,然后apply一下,这时就会在这个DataFrame中执行这个操作了。

10.1 关于apply(自定义函数名) 的第一个例子

具体如下所示:

需求:我们想要返回数据集合的第100行数据。

过程:先定义一个返回第100行数据的函数hundredth_row ,然后在apply一下

#定义一个新的函数hundredth_row,用来返回第100行数据
def hundredth_row(column):
    hundredth_item = column.loc[99]
    return hundredth_item

hundredth_row = titanic_survival.apply(hundredth_row)   #将新定义好的函数apply一下
print(hundredth_row)

运行结果:

10.2 关于apply(自定义函数名) 的第二个例子

  用apply(自定义函数名)来得到每一个属性缺失值的个数。

#返回所有属性缺失值的个数
def isnull_count(column):
    column_null = pd.isnull(column)        #返回值是true或flase
    null = column[column_null]             #缺失值列表
    return len(null)

column_null_count = titanic_survival.apply(isnull_count)
print(column_null_count)

运行结果:

10.3 关于apply(自定义函数名) 的第三个例子

用apply(自定义函数名)来对船舱等级【1,2,3】进行一个改写,改成First Class,Second Class ,Third Class

#将船舱等级进行一个转化,1——First Class....
def which_class(row):
    pclass = row["Pclass"]
    if pd.isnull(pclass):
        return "UnKnown"
    elif pclass == 1:
        return "First Class"
    elif pclass == 2:
        return "Second Class"
    elif pclass == 3:
        return "Third Class"
    
classes = titanic_survival.apply(which_class,axis = 1)
print(classes)

运行结果:

10.4 关于apply(自定义函数名) 的第四个例子

将年龄离散化,在本实例数据集上的“Age”是一个连续的值,这里以18为界限,将其离散化。

def generate_age_label(row):
    age = row["Age"]
    if pd.isnull(age):
        return "Unknow"
    elif age < 18:
        return "minor"
    else:
        return "adult"

age_labels = titanic_survival.apply(generate_age_label, axis = 1)
print(age_labels)

运行结果:

友情赠送

利用上边的自定义函数,使用.pivot_table()函数得到年龄阶段与获救率之间的关系。

titanic_survival["age_labels"] = age_labels      #将上一个里边返回的关于age_labels的数据组合成数据的一列
#得到年龄阶段与存活率之间的关系
age_group_survival = titanic_survival.pivot_table(index = "age_labels",values = "Survived")
print(age_group_survival)

运行结果:

 

posted @ 2018-04-06 22:58  顽皮小丸子  阅读(6496)  评论(0编辑  收藏  举报