分享

统计师的Python日记【第十天:数据聚合】

 三郞 2018-01-07


回顾一下:


  • 第1天学习了Python的基本页面、操作,以及几种主要的容器类型。

  • 第2天学习了python的函数、循环和条件、类。

  • 第3天了解了Numpy这个工具库。

  • 第4、5两天掌握了Pandas这个库的基本用法。

  • 第6天学习了数据的合并堆叠。

  • 第7天开始学习数据清洗,着手学会了重复值删除、异常值处理、替换、创建哑变量等技能。

  • 第8天接着学习数据清洗,一些常见的数据处理技巧,如分列、去除空白等被我一一攻破

  • 第9天学习了正则表达式处理文本数据


原文复习(点击查看):


【第1天:谁来给我讲讲Python?】


【第2天:再接着介绍一下Python呗】


【第3天:Numpy你好】


【第4天:欢迎光临Pandas】


【第四天的补充


【第5天:Pandas,露两手】


【第6天:数据合并】


【第7天:数据清洗(1)】


【第8天:数据清洗(2)文本处理】


【第9天:正则表达式】


今天将带来第10天的学习日记。


目录如下:


前言


1. 聚合运算

(1)groupby:按照变量进行分组

(2)按照函数进行分组

(3)用agg()自定义聚合函数


2. 数据透视表

(1)pivot_table()方法

(2)交叉表crosstab





统计师的Python日记【第10天:数据聚合】


前言


根据我的Python学习计划:


Numpy → Pandas 掌握一些数据清洗、规整、合并等功能掌握正则表达式 掌握类似与SQL的聚合等数据管理功能 → 能够用Python进行统计建模、机器学习等分析技能 → 能用Python打印出100元钱 → 能用Python帮我洗衣服、做饭 → 能用Python给我生小猴子......


其实前面在学合并的时候已经学过类似的功能了:左连接、右连接、内连接、全连接(第6天:数据合并)。今天来学数据的聚合。什么叫聚合呢?来看个例子:


有一份数据,数据名为family:




变量如下:

  • fam:家庭编号,有三个家庭fam1、fam2、fam3;

  • gender:性别

  • salary:成员的月收入


从这份名单中大概能猜到,fam1有三个成员,可能是一个三口之家;fam2有5位成员,也许是四世同堂;fam2有2位成员,应该是两口子,不过这不重要。


现在,想知道每个家庭的成员平均月收入,应该如何处理?


学过SQL的人知道,典型的SQL查询语句应该是:


select mean(salary) from family group by fam


从数据family这份数据中,找出每个fam group下的mean(salary)。这是一个典型的数据聚合的例子,现在如果想用Pandas来实现,应该如何处理?



1. 聚合运算


(1)groupby:按照变量进行分组


要实现这个目的,使用 groupby 语句即可。


按照下图所示,进行两步操作:


  • 先groupby一下:salFam = family['salary'].groupby['fam']

  • 再求均值salFam.mean()




于是就得到了聚合函数的第一种写法

family['salary'].groupby(family['fam']).mean()


大图解释:




结果为:

这个例子是对fam进行分组求mean(salary),也就是对fam进行groupby,当然也可以对两个变量一起进行groupby,比如对salary按照fam、gender分组求mean:


  • salFamGen = family['salary'].groupby( [ family['fam'],family['gender']] )

  • salFamGen.mean()


注意标红的中括号,这是传入的是一个list了,结果如下:




不过我觉得这样看起来特别不美丽,可以用unstack变成透视表,这个在第五天(第5天:Pandas,露两手)已经学过了:

 

  • salFamGen =family['salary'].groupby([family['fam'],family['gender']])

  • salFamGen.mean().unstack()




第二种写法


还有一种写法是这样的:family.groupby('fam')['salary'].mean()



结果为:




一次性对多个变量进行groupby这么写:


family.groupby( [ ‘fam’, ‘gender’ ] )[‘salary’]

 

不指明salary,则代表对family所有连续变量进行groupby。后面其他功能都与第一种写法类似。

 

这个第二种写法是第一种的语法糖,什么叫语法糖?简单来说就是编程语言中可以更容易的表达一个操作的语法,它可以使程序员更加容易去使用这门语言:操作可以变得更加清晰、方便,或者更加符合程序员的编程习惯。


(2)按照函数进行分组


刚刚是对变量进行groupby,还可以直接对函数进行groupby。函数的对象是索引。比如oct(x)这个函数是将x转换成八进制,那么如果对oct进行groupby,比如:


family.groupby(oct).count()

 

那么就是对原数据的索引求八进制,再进行count




如果索引是字符串,还可以有更多玩法,比如数据是这样的:




索引是每个人的名字,那么现在可以对名字的占位长度进行GroupBy:




好吧,暂时就想到这么多。


(3)用agg()自定义聚合函数

 

前面的聚合函数:mean()/ sum()/ count()等等,都是内置的,其实也可以自定义,自定义函数之后,要结合agg使用。比如定义一个最大值的两倍:

 

def max2(ser):

   return 2*ser.max()

 

family.groupby('fam')['salary'].agg(max2)


结果为:




如果自定义的聚合函数为fun(),那么groupby中要以agg(fun)的形式使用。

 

agg()不仅可以发挥自定义聚合函数的作用,还可以一次性对多个函数进行聚合运算:

 

family.groupby('fam')['salary'].agg(['mean','sum', max2])


结果为:




注意调用的函数不加引号

 

这里的列名还可以改,比如不想用max2这个列名,想用2*max,在自定义函数的时候因为不能以数字开头所以只能写成max2,那么这里可以用(‘2*max’, max2)来改名字:

 

family.groupby('fam')['salary'].agg(['mean','sum', (‘2*max’,max2)])




还可以对不同的列应用不同的聚合函数,使用字典可以完成 {列1:函数1, 列2:函数2},然后再用agg()包起来:


family.groupby('fam')['salary'].agg({'salary':'mean','gender':'count'})





2. 数据透视表


在第5天的日记中,提到过“数据透视表”(第5天:Pandas,露两手):




现在看来,这个unstack()完全不能算“透视表”,因为今天要学pivot_table()方法和pandas.pivot_table()方法。

 

(1)pivot_table()方法

 

比如,以fam这个列变量维度进行透视:


family.pivot_table(columns='fam')




以fam、gender这两个维度进行透视:




添加margins=True可以为透视表添加总计:




除了margins选项,还有其他选项可以辅助:




(2)交叉表crosstab


因为是统计师,经常会做卡方检验,所以对列联表或者是交叉表很熟悉,就是看交叉分组下的频数。现在想做一个fam和gender的列联表:

 

pd.crosstab(family.fam, family.gender,margins=True)




也可以做成三维的:

 

pd.crosstab( [family.salary, family.fam],family.gender, margins=True )





好啦,到今天已经是第10天了,Python的数据处理已经结束,下一篇日记打算开始学习Python的统计分析模块。在此之前您还有什么建议请给我留言。




1. 授权白名单请给数说君留言


2. 关于数据分析的提问求助,可以在分答中搜索“数说君”找我


3. 点击链接→数据分析合作小组,查看数据分析合作小组


4. 投稿、免费发布招聘、合作,请加数说君个人微信AnselT,或Email:jiayounet@163.com。


    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多