回顾一下:
原文复习(点击查看): 今天将带来第10天的学习日记。 目录如下: 前言 1. 聚合运算 (1)groupby:按照变量进行分组 (2)按照函数进行分组 (3)用agg()自定义聚合函数 2. 数据透视表 (1)pivot_table()方法 (2)交叉表crosstab 统计师的Python日记【第10天:数据聚合】 前言 根据我的Python学习计划:
其实前面在学合并的时候已经学过类似的功能了:左连接、右连接、内连接、全连接(第6天:数据合并)。今天来学数据的聚合。什么叫聚合呢?来看个例子: 有一份数据,数据名为family: 变量如下:
从这份名单中大概能猜到,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 语句即可。 按照下图所示,进行两步操作:
于是就得到了聚合函数的第一种写法: family['salary'].groupby(family['fam']).mean() 大图解释: 结果为: 这个例子是对fam进行分组求mean(salary),也就是对fam进行groupby,当然也可以对两个变量一起进行groupby,比如对salary按照fam、gender分组求mean:
注意标红的中括号,这是传入的是一个list了,结果如下: 不过我觉得这样看起来特别不美丽,可以用unstack变成透视表,这个在第五天(第5天:Pandas,露两手)已经学过了:
第二种写法 还有一种写法是这样的: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。 |
|
来自: 三郞 > 《统计师的Python日记》