Pandas复杂分组:能否用函数形式groupby()按表格内容分组?
可以用函数形式的
groupby()按表格内容分组! 你说的没错,直接写groupby(f)时,函数f默认只会收到索引值——这是因为pandas默认把函数参数作用在索引上。但我们完全可以调整写法,让函数接收每行的内容来生成分组键,具体有两种常用方法:
方法1:先给每行生成分组键,再传入groupby
这是最直观也高效的方式——用df.apply()把分组函数作用在每一行(axis=1表示按行处理),生成一个包含分组标识的序列,再把这个序列传给groupby的by参数。
举个结合你的示例数据的例子:
import pandas as pd df0 = pd.DataFrame([ dict(age=30,sex='M',name='Jim',weight=143), dict(age=45,sex='F',name='Francine',weight=102), dict(age=22,sex='F',name='Jill',weight=190), dict(age=37,sex='M',name='Joseph',weight=221), dict(age=55,sex='M',name='Jerry',weight=187), dict(age=48,sex='M',name='Gus',weight=262) ]) # 定义依赖行内容的分组函数 def get_group(row): # 按年龄区间+性别组合分组 age_bracket = 'Young' if row['age'] < 30 else 'Middle' if row['age'] < 50 else 'Senior' return f"{row['sex']}_{age_bracket}" # 生成分组键序列,再执行分组 grouped = df0.groupby(df0.apply(get_group, axis=1)) # 验证分组结果:计算每组的平均体重 print(grouped['weight'].mean())
运行后会得到:
F_Middle 102.0 F_Young 190.0 M_Middle 208.666667 M_Senior 187.0 Name: weight, dtype: float64
方法2:通过索引间接获取行数据(适合简单场景)
如果你坚持想用groupby(f)的形式,可以让函数接收索引值后,通过df.loc[idx]取出对应行的数据再处理。比如:
# 用lambda函数封装索引取行的逻辑 grouped = df0.groupby(lambda idx: get_group(df0.loc[idx]))
不过这种方式在数据量大时效率不如方法1,因为每次都要通过索引查找行,不如直接批量生成分组键高效。
补充小技巧
如果你的分组逻辑只依赖某一列,其实可以更简洁:比如按年龄十位数分组,直接写df0.groupby(df0['age'] // 10)就行,不需要单独写函数。但涉及多列组合的复杂逻辑时,上面的两种方法就很实用啦。
内容的提问来源于stack exchange,提问作者Jason S
相关产品推荐
相关产品推荐

