您的位置:首页 > 编程语言 > Python开发

利用pandas进行数据分组及可视化

2016-01-14 22:01 411 查看


利用pandas进行数据分组及可视化

kaggle的Titanic数据集,给定了Titanic号邮轮的乘客的船舱等级(Pclass)、性别(Sex)、年龄(Age)、是否获救(Survived)等信息。希望能够用这些信息建立一个分类系统,来预测一个人是否会获救。

使用python,先导入numpy、pandas、matplotlib等库和数据train.csv

import numpy as np

import pandas as pd

import matplotlib.pyplot as plt

from pandas import DataFrame,Series

data=pd.read_csv(r'D:\Titanic\train.csv')

data



data.info()



很明显Age是一个很重要的属性,不是都说“让老人和小孩先走”嘛。可惜在891个实例中,有177个人缺失了这个属性。所以我们希望可以用机器学习等方法来用其它数据推断出这几个人的大致年龄。将训练集补全,也是数据清洗的一部分。

这里我比较好奇Pclass和Age是否有关系,这篇文章就是用数据可视化的方法来研究。

 

首先希望能把每个Pclass的人按照Age分成0—20,20—40,40—80三组,再画出bar来确认之间的关系。

代码如下,t为DataFrame:

teen1 = t[(t.Pclass == 1) &(t.Age<20)]['PassengerId'].count()

four1=t[(t.Pclass == 1) & (t.Age>20) & (t.Age < 40)]['PassengerId'].count()

six1=t[(t.Pclass == 1) & (t.Age >40)& (t.Age < 80)]['PassengerId'].count()

teen2 = t[(t.Pclass == 2) &(t.Age<20)]['PassengerId'].count()

four2=t[(t.Pclass == 2) & (t.Age>20) & (t.Age < 40)]['PassengerId'].count()

six2=t[(t.Pclass == 2) & (t.Age >40)& (t.Age < 80)]['PassengerId'].count()

teen3 = t[(t.Pclass == 3) & (t.Age<20)]['PassengerId'].count()

four3=t[(t.Pclass == 3) & (t.Age>20) & (t.Age < 40)]['PassengerId'].count()

six3=t[(t.Pclass == 3) & (t.Age >40)& (t.Age < 80)]['PassengerId'].count()

allteen = t[t.Age<20]['PassengerId'].count()

allfour=t[ (t.Age >20) & (t.Age < 40)]['PassengerId'].count()

allsix=t[ (t.Age >40 )& (t.Age <80)]['PassengerId'].count()

s=DataFrame({'all':[allteen,allfour,allsix],'P1':[teen1,four1,six1],'P2':[teen2,four2,six3],'P3':[teen3,four3,six3]},index=['0-20','20-40','40-'])

s.plot(kind='bar')

plt.show()



图还是很漂亮的,但是有一个问题:只是分成3组就写了这么多重复的代码,要是需要10组呢?这不符合python简洁的美啊!

接下来就是要解决这个问题。

首先能想到这个功能和groupby总是有点关系的,所以希望利用这个内置的函数。但是是对什么属性进行groupby呢?我们需要为每个实例加一个属性,代表它所在的group,那么要设计一个映射函数:

def cla(n,lim):

return'[%.f,%.f)'%(lim*(n//lim),lim*(n//lim)+lim) # map function

这里n是输入的数据,lim是每个年龄段的长度。

生成这样一个Series,并加入到DataFrame中:

addone = Series([cla(s,10) for s in t.Age])

t['addone'] = addone

处理完的data是这个样子的,注意到多了addone这一个属性



然后我们就可以groupby啦

groups = t.groupby(['Pclass','addone']).count()   # beautiful graph

groups是这样一个DataFrame



然后画图:

groups['PassengerId'].plot('bar')

plt.show()



但这并不是我们需要的。

注意到是一个层次化索引,取出其中的任意一列:

tmp = groups['Name']

这是一个Series



只要把它的双重索引转化成xy索引的DataFrame,就能画出需要的图了:

tmp2 = tmp.unstack()

tmp2如下:



这就是我们需要的了,可以直接画图:

tmp2.plot(kind='bar')

plt.show()



似乎横纵坐标弄反了,只要转置一下就行:

(tmp2.T).plot(kind='bar')

plt.show()



 

这就是我们需要的图了。从这张图上我们可以发现,年纪越大的人,坐高等级仓位的概论就越大,而年龄缺失的人里,绝大部分都是坐3等仓的。有了这个结论,利用sklearn等机器学习库进行预测时,Pclass这个属性是一定要当作特征加进去的。

总的代码如下:

lim = 10

def cla(n,lim):

return '[%.f ,%.f)'% (lim*(n//lim) , lim*(n//lim)+lim)

addone = Series([cla(s,lim) for s int.Age])

t['addone'] = addone

groups = t.groupby(['Pclass','addone']).count()

(groups['Name'].unstack()).plot(kind = ’bar’)

plt.show()

只用这么短的几行代码,就能画出来这么美的图,可见python这门语言本身的美和各库的强大.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  python 可视化