如何在Pandas DataFrame中按组执行函数并按行(axis=0)拼接结果?
高效实现按分组处理DataFrame并拼接结果
问题背景
我有如下结构的DataFrame:
cell_id col1 col2 en_1 2.0 3.0 en_2 8.0 9.0 ... en_2 9.0 8.0 en_1 9.0 8.0 ... en_n 4.0 6.7
需要按cell_id分组,将每组的子DataFrame传入自定义函数处理后,按行拼接所有结果。手动实现的方式如下,但需要优化效率:
def func(df): # 自定义处理逻辑 do_some_process return df # 手动逐个处理分组(效率低) result1 = func(df[df.cell_id.eq('en_1')]) result2 = func(df[df.cell_id.eq('en_2')]) ... result_n = func(df[df.cell_id.eq('en_n')]) result = pd.concat([result1, result2,.....,result_n], axis=0)
高效实现方案
方法一:groupby().apply()(推荐)
这是最简洁高效的方式,Pandas的groupby配合apply会自动遍历每个分组的子DataFrame,传入func处理后自动拼接结果:
# 基础用法 result = df.groupby('cell_id').apply(func) # 保持原分组顺序(默认groupby会对分组键排序,不需要排序就加sort=False) result = df.groupby('cell_id', sort=False).apply(func)
- 只要
func返回的是DataFrame或Series,apply就会自动按行拼接所有分组的处理结果,和手动concat的效果完全一致。
方法二:groupby()配合列表推导式+concat
如果需要更灵活的分组遍历控制,可以用列表推导式遍历分组对象,再拼接结果:
# 遍历分组对象,处理后拼接 groups = df.groupby('cell_id', sort=False) result = pd.concat([func(group) for _, group in groups], axis=0)
这种方式比手动逐个筛选cell_id高效得多,因为groupby已经提前完成了数据分组的逻辑,避免了多次重复筛选的开销。
性能提示
- 相比手动逐个筛选分组,上述两种方法都避免了重复查询DataFrame的操作,数据量越大,性能提升越明显。
- 如果你的
func逻辑可以向量化(比如仅做聚合、列运算),优先用groupby.transform()或groupby.agg()这类专用方法,性能会比apply更高;但如果是必须处理整个子DataFrame的复杂逻辑,apply是最优选择。
内容的提问来源于stack exchange,提问作者Rajan Kumar Yadav
相关产品推荐
相关产品推荐

