【Python】GroupBy:数据聚合与分组运算
⽬录:
⽂章⽬录
对数据集进⾏分组并对各组应⽤⼀个函数(⽆论是聚合还是转换),这是数据分析⼯作中的重要环节。在将数据集准备好之后,通常的任务就是计算分组统计或⽣成透视表。pandas提供了⼀个灵活的groupby功能,它能够以⼀种⾃然的⽅式对数据集进⾏切⽚、切块、摘要等操作。
关系型数据库和SQL能够流⾏的原因之⼀就是能够⽅便地对数据进⾏连接、过滤、转换和聚合等。
python和pandas强⼤的能⼒,有助于执⾏更复杂的分组运算,如:
根据⼀个或多个键(可以是函数、数组或DataFrame列名)拆分pandas对象
计算分组摘要统计,如计数、平均值、标准差或⽤户⾃定义函数
对DataFrame的列应⽤各种各样的函数
应⽤组内转换或其他函数,如规格化、线性回归、排名或选取⼦集等
计算透视表或交叉表等
执⾏分位数分析以及其他分组分析
⼀ GroupBy技术
split-apply-combine(拆分-应⽤-合并),基本描述了groupby的整个过程。分组运算的第⼀个阶段,pandas对象中的数据会根据提供的键被拆分为多组,拆分操作是在对象的特定轴上执⾏的;然后将⼀个函数应⽤在各个分组并产⽣⼀个新值;最后,所有这些函数的执⾏结果会被合并到最终的结果对象中。
分组键可以有多种形式,且类型不必相同:
列表或数组,其长度与待分组的轴⼀样
表⽰DataFrame某个列名的值
字典或Series,给出待分组轴上的值与分组名之间的对应关系
函数,⽤于处理轴索引或索引中的各个标签
分组产⽣的变量grouped是⼀个GroupBy对象,实际上还没有进⾏任何计算,只是含有⼀些有关分组键的中间数据。换句话说,该对象已经有了接下来对各分组执⾏运算所需的⼀切信息。数据Series根据分组键进⾏了聚合,产⽣了⼀个新的Seriesgroupby分组
如果通过两个键对数据进⾏分组,得到的Series具有⼀个层次化索引
分组键可以为Series,也可以是任意长度的数组,还可以是列名
分组过程中的“⿇烦列”会在结果中被踢出。默认情况下,所有数值列都会被聚合,虽然有时可能会被过滤为⼀个⼦集。
⽆论准备拿groupby⼲啥,都可能会⽤到groupby的size⽅法,它可以返回⼀个含有分组⼤⼩的Series
1 对分组进⾏迭代
GroupBy对象⽀持迭代,可以产⽣⼀组⼆元元组(由分组名和数据块组成)
for name,group upby(key1)
print(name)
print(group)
对于多重键的情况,元组的第⼀个元素将会是由键值组成的元组
for (k1,k2) ,group upby(['key1','key2'])
print(k1,k2)
print(group)
也可以对这些数据⽚段进⾏任何操作,例如:将这些数据⽚段做成⼀个字典:
pieces = dict(upby('key1')))
peices['b']
groupby默认是在axis = 0上进⾏分组的,也可以设置在其他任何轴上进⾏分组
2 选取⼀个或⼀组列
对于由DataFrame产⽣的groupby对象,如果⽤⼀个或⼀组列名对其进⾏索引,就能实现选取部分列进⾏聚合的⽬的。尤其对于⼤数据集,很可能只需要对部分列进⾏聚合。
3 通过字典或Series进⾏分组
通过字典分组只需要将这个字典传给groupby即可
people = DataFrame(np.random.randn(5,5),columns = ['a','b','c','d','e'],idnex = ['joe','steve','wes','jim','travis'])
people.ix[2:3,['b','c']] = np.nan  #添加⼏个缺失值
mapping = {'a':'red','b':'red','c':'blue','d':'blue','e':'red','f':'orange'}
by_column = upby(mapping,axis = 1)
Series也有同样的功能,它可以被看做⼀个固定⼤⼩的映射,pandas会检查Series以确保其索引跟分组轴是对齐的。
4 通过函数进⾏分组
相较于字典或Series,python函数在定义分组映射关系时可以更有创意且更为抽象。任何被当做分组
键的函数都会在各个索引值上被调⽤⼀次,其返回值就会被⽤作分组名称。
将函数跟数组、列表、字典、Series混合使⽤也可以,因为任何东西最终会被转换为数组。
5 根据索引级别进⾏分组
层次化索引数据集最⽅便的地⽅就在于它能够根据索引级别进⾏聚合。要实现该⽬的,通过leve关键字传⼊级别编号或名称即可。
columns = pd.MultiIndex.form_arrays([['US','US','US','JP','JP'],[1,3,5,1,3]],names = ['cty','tenor'])
hier_df = DataFrame(np.random.randn(4,5),columns = columns)
upby(level = 'cyt',axis = 1).count
⼆数据聚合
对于聚合,指的是任何能够从数组产⽣标量值的数据转换过程。许多常见的诸如mean、sum、count、min等聚合运算都有就地计算数据集统计信息的优化实现。然后,并不只能使⽤这些⽅法,可以使⽤⾃⼰发明的聚合运算,还可以调⽤分组对象上已经定义好的任何⽅法。
如果要使⽤⾃⼰定义的聚合函数,只需将其传⼊aggregate或agg⽅法即可
经过优化的groupby⽅法:
count # 分组中⾮NA值得数量
sum # ⾮NA值的和
mean # ⾮NA值的平均数
median # ⾮NA值的算术中位数
std、var # ⽆偏标准差和⽅差
min、max # ⾮NA值的最⼩值和最⼤值
prod # ⾮NA值的积
first、last # 第⼀个和最后⼀个⾮NA值
有些⽅法也可以⽤在这⾥,但严格来讲,它们并⾮聚合运算。
1 ⾯向列的多函数应⽤
对Series或DataFrame列的聚合运算其实就是使⽤aggregate(使⽤⾃定义函数)或调⽤诸如mean、std之类的⽅法。然后,可以对不同的列使⽤不同的聚合函数,或⼀次应⽤多个函数。
如果传⼊⼀组函数或函数名,得到的DataFrame的列就会以相应的函数命名
并⾮⼀定要接受groupby给出的列名,特别是lambda函数,辨识度很低。如果传⼊的是⼀个由(name,function)元组组成的列表,则各元组的第⼀个元素就会被⽤作DataFrame的列名(可以将⼆元元组看做⼀个有序映射)。
对于DataFrame,还可以定义⼀个应⽤于全部列的函数,或不同的列应⽤不同的函数。如果DataFrame拥有层次化的列,相当于分别对各列进⾏聚合,然后⽤concat将结果组合在⼀起(列名⽤作keys参数)。
想要对不同的列应⽤不同的函数,具体的⽅法是向agg传⼊⼀个列名映射到函数的字典。
2 以“⽆索引”形式返回聚合数据
可以向groupby传⼊as_index = False以禁⽤由分组键组成的索引这⼀功能。对结果调⽤reset_index也能得到这种形式的结果。
三分组级运算和转换
聚合只不过是分组运算的其中⼀种⽽已。它是数据转换的⼀个 特例,也就是说,它接受能够将⼀维数组简化为标量值的函数。
transform和apply⽅法,能够执⾏更多其他的分组运算。
1 apply:⼀般性的“拆分-应⽤-合并”
跟aggregate⼀样,transform也是⼀个有着严格条件的特殊函数:传⼊的函数只能产⽣两种结果,要么产⽣⼀个可以⼴播的标量值,要么产⽣⼀个相同⼤⼩的结果数组。最⼀般化的groupby⽅法是apply,apply会将待处理的对象拆分成多个⽚段,然后对各⽚段调⽤传⼊的函数,最后尝试将各⽚段组合到⼀起。
如果传给apply的函数能够接受其他参数或关键字,则可以将这些内容放在函数名后⾯⼀并传⼊。
除⼀些基本⽤法外,能否充分发挥apply的威⼒很⼤程度上取决于你的创造⼒。传⼊的那个函数能做什么全由你说了算,它只需要返回⼀个pandas对象或标量值即可。
result = upby('smoker')['tip_pit'].describe()
禁⽌分组键
2 分位数和桶分析
pandas有⼀些能够根据指定⾯元或样本分位数将数据拆分成多块的⼯具(⽐如cut或qcut)。将这些函数跟groupby结合起来,就能⾮常轻松地实现对数据集的桶(bucket)或分位数(quantile)分析
1)⽰例:⽤特定分组的值填充缺失值
2)⽰例:随机采样和排列
3)⽰例:分组加权平均数和相关系数
4)⽰例:⾯向分组的线性回归
四透视表和交叉表
1 透视表
透视表(pivot_table)是各种电⼦表格 程序和其他数据分析软件中⼀种常见的数据汇总⼯具。它根据⼀个或多个键对数据进⾏聚合,并根据⾏和列上的分组键将数据分配到各个矩形区域中。在python和pandas中,可以通过groupby功能以及层次化索引的重塑运算制作透视表。DataFrame有⼀个pivot_table⽅法,此外还有⼀个顶级的pandas.pivot_table函数。除能为groupby提供便利
外,pivot_table还可以添加分项⼩计。
pivot_table的参数
① values # 待聚合的列的名称,默认聚合所有数值列
② rows # ⽤于分组的列名和其他分组键,出现在结果透视表的⾏
③ cols # ⽤于分组的列名或其他分组键,出现在结果透视表的列
④ aggfunc # 聚合函数或函数列表,默认为mean,可以是任何对groupby有效的函数
⑤ fill_value # ⽤于替换结果表中的缺失值
⑥ margins # 添加⾏、列⼩计和总计,默认为False
tips.pivot_table('tip_pct',rows = ['sex','smoker'],cols = 'day',aggfunc = len,margins = True)
2 交叉表
交叉表(crosstab)是⼀种⽤于计算分组频率的特殊透视表
假设我们想要根据某两个特征对数据进⾏汇统计汇总,虽然pivot_table可以实现该功能,但sstab函数会更加⽅便。
五 END

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。