// Pandas分组聚合
创建对象:姓名、历次测验语文成绩,数学成绩,英语成绩
df = pd.DataFrame({
'name': ['张三','李四','王五','李四','王五','王五','赵六'],
'chinese':np.random.randint(35,100,7),
'math':np.random.randint(35,100,7),
'english':np.random.randint(35,100,7),
'test': ['一','一','一','二','二','三','一']
})
df
df.index,df.columns
统计分析:
# 按列求科目成绩平均值
df.mean()
# 按行求学生每次考试平均值
df.mean(axis='columns')
# 快速综合统计
df.describe()
分组:
groupby(),一般指以下一个或多个操作步骤的集合
- Splitting 将数据分组
- Applying 对每个分组应用不同的function
- Combining 使用某种数据结果展示结果
# 创建group对象,未进行计算
df.groupby('name')
# 调用函数做分组计算,分组后求每组平均值
# 可将列名或列值当作分组对象,分组中数值列会被聚合,非数值列会从结果中排除
a = df.groupby('name').mean()
# 如果不想使用分组列作为索引,设置参数as_index=False
b = df.groupby('name',as_index=False).mean()
# 对多列分组后求平均值
c = df.groupby(['name','chinese']).mean()
c2 = df.groupby(['name','chinese'],as_index=False).mean()
更多操作:
# 分组数据的个数
df.groupby('name').size()
# 遍历分组对象
for (method, group) in df.groupby('name'):
# print(method)
# print(group)
print(group.shape)
# 对分组后的部分列做统计
df.groupby('name')['math'].describe()
# 行列旋转
df.groupby('name')['math'].describe().unstack()
聚合:
aggregate(),或agg()
aggregate函数的参数:
- 参数可以是列表,列表元素是指标的计算函数或特定的指标名字符串
- 参数可以是字典,函数会根据字典内容对指定列进行不同的指标计算
- 参数可以是系统或自定义函数,各分组都进行计算后返回结果
df
# 分组
df.groupby('name').mean()
# 聚合参数是列表
d = df.groupby('name').aggregate(['min',max,np.mean])
# 聚合参数是字典
df.groupby('name').aggregate({'chinese':'min','math':'max'})
# 聚合是自定义函数
def hs(arr):
return arr.mean()-1
df.groupby('name').agg(hs)
其他分组运算
运用 groupby 函数进行分组后,我们能做的事情还有很多,并不局限于聚合汇总
利用 fliter 函数来对分组进行筛选,留下符合条件的分组:
def filter_func(x):
return x['math'].mean() >= 60 # 数学成绩平均值大于等于60分
e = df.groupby('name').filter(filter_func)
e.groupby('name').mean()
使用 transform 函数对所有的数据元素进行转换计算:
# 所有列减去60
df.groupby('name').transform(lambda x: x - 60)
运用 apply 函数,我们可以一次性对所有的分组进行不同规则的运算:
# 某列单独计算
def a2(x):
x['chinese'] = x['chinese'] + 10
x['english'] -= 10
return x
df.groupby('name').apply(a2)
在 groupby 函数的输入中自定义分配每一行记录所属的分组
如果我们的输入就是原始数据集 df 中的某一列,那么这一列将被作为分组的依据,这种方法比直接输入列名要显得麻烦一些
# 传入结构一样的列,传入索引会替换掉原索引
df.groupby(['张三','李四','王五','李四','王五','王五','张三']).mean()
df.groupby([0,0,0,0,0,0,0]).mean()
groupby 函数将会根据索引值进行分组,我们可以通过输入一个字典对象的方式,来给不同的索引值重新分配组别:
df2 = df.set_index('name')
df2
# 合并行计算
mapping = {'张三': '一个人', '赵六': '一个人', '李四': '李四new'}
df2.groupby(mapping).mean()
# 通过输入一个列表的形式来使多种映射同时生效:
df2.groupby(['name', mapping]).mean()
综合应用:输出所有人在所有测试中的数学成绩
# 所有人在所有测试中的数学成绩
df.groupby(['name',df['test']])['math'].mean().unstack().fillna(0)