如何基于另一DataFrame的指定列对Pandas DataFrame执行groupby分组
报错原因
你直接传入df2[['col1', 'col2']]会触发报错,是因为pandas的groupby的by参数默认不接受二维的DataFrame作为分组器,只支持一维的序列/索引、或者由多个一维分组器组成的列表。
简洁实现方法
下面给出三种常用的简洁写法,你可以根据使用场景选择:
方法1:列表推导式(兼容性最好)
如果你的分组列已经整理成了列表变量,直接用列表推导式生成多个分组器的列表即可,不需要逐个手动写df2['xxx']:
# 先定义你要用到的df2分组列 group_cols = ['col1', 'col2', 'col3', 'col4'] # 直接传入推导式生成的分组器列表 df1.groupby([df2[col] for col in group_cols])
这个方法兼容所有pandas版本,分组结果会自动保留df2的列名作为分组键的标识,后续处理最方便。
方法2:转元组序列(写法最短)
把df2的多列按行聚合为一维的元组序列作为分组器:
df1.groupby(df2[['col1', 'col2']].agg(tuple, axis=1))
这个写法最简洁,但分组后的组名会以元组形式展示,不会保留原列名,适合只需要聚合计算、不需要后续处理分组键信息的场景。
方法3:转多级索引(保留元信息最完整)
用pandas内置的MultiIndex.from_frame接口直接把df2的多列转为多级索引作为分组器:
import pandas as pd df1.groupby(pd.MultiIndex.from_frame(df2[['col1', 'col2']]))
这个方法的分组结果会自动生成为多级索引,完整保留df2的列名作为层级名称,适合需要对分组结果做进一步索引操作的场景。
效果验证示例
你可以用下面的测试代码验证三种写法的效果,和你原来手动传入多个df2[col]的结果完全一致:
import pandas as pd import numpy as np # 构造两个同索引的测试DataFrame df1 = pd.DataFrame({'value': np.random.randn(6)}, index=range(6)) df2 = pd.DataFrame({ 'col1': ['A','A','A','B','B','B'], 'col2': [1,1,2,2,3,3] }, index=range(6)) # 三种写法的分组求和结果完全一致 res1 = df1.groupby([df2['col1'], df2['col2']]).sum() res2 = df1.groupby([df2[col] for col in ['col1','col2']]).sum() res3 = df1.groupby(pd.MultiIndex.from_frame(df2[['col1','col2']])).sum() print(res1.equals(res2)) # 输出True print(res1.equals(res3)) # 输出True
内容的提问来源于stack exchange,提问作者Stalpotaten
相关产品推荐
相关产品推荐

