利用python进行数据处理的时候,经常会使用到pandas这一强大的数据处理模块。将数据存储为DataFrame形式,进行一系列的操作。
有些时候我们需要对DataFrame对象进行像sql里面group by聚合操作,pandas也提供了非常好用的api。
在pandas中,聚合操作主要由groupby来完成。该篇文章讲述groupby常用方法以及怎么处理groupby产生的MultiIndex。
利用groupby进行分组
# 先构造一组数据
import pandas as pd
df = pd.DataFrame({
'year': [1995, 1996, 1995, 1997, 2000],
'name': ['Lil', 'Bob', 'Clc', 'Aba', 'Joj'],
'gender': ['F', 'M', 'F', 'F', 'M', ],
'height': [168, 180, 159, 160, 175]
})
# 对gender进行聚合操作
gdf = df.groupby(['gender'])
print(gdf)
# 生成了一个生成器DataFrameGroupBy对象
#<pandas.core.groupby.generic.DataFrameGroupBy object at 0x000001C5C9571B80>
print(list(gdf))
# 打印结果如下
[('F', year name gender height
0 1995 Lil F 168
2 1995 Clc F 159
3 1997 Aba F 160), ('M', year name gender height
1 1996 Bob M 180
4 2000 Joj M 175)]
# 生成了一个由元组组成的列表,元组里面又包括了一个聚合的字段和一个DataFrame对象
由上面代码可以看出,groupby的过程就是将原有的DataFrame对象划分为按要求聚合好的多个子DataFrame对象,后续的聚合函数都是基于这些子DataFrame对象进行的。
直接对非聚合的列调用聚合函数
gdf['height'].max()
# 输出
gender
F 168
M 180
Name: height, dtype: int64
这里的gender列是以索引的形式存在的,还原数据框的方法
gdf['height'].max().reset_index()
# 输出
gender height
0 F 168
1 M 180
使用agg进行更灵活的聚合
gdf['height'].agg(['min', 'max'])
# 输出
min max
gender
F 159 168
M 175 180
gdf.agg(['min', 'max'])
# 输出
year name height
min max min max min max
gender
F 1995 1997 Aba Lil 159 168
M 1996 2000 Bob Joj 175 180
gdf.agg({'height':['min', 'max']})
# 输出
height
min max
gender
F 159 168
M 175 180
gdf.agg({'height':['min', 'max']}).reset_index()
# 输出
gender height
min max
0 F 159 168
1 M 175 180
如上代码所示,可以注意到使用了reset_index()重塑了索引,但还是会出现MultiIndex的情况出现
解决办法
# 使用pd.NameAgg()来为聚合后的每一列设置新的列名
gdf.agg(
min_height = pd.NamedAgg(column='height',aggfunc='min'),
max_height = pd.NamedAgg(column='height',aggfunc='max'),
).reset_index()
# 输出
gender min_height max_height
0 F 159 168
1 M 175 180