Pandas按列分组后如何对多列实现条件计数分箱统计
解决方案
不需要逐列生成临时表再合并,也不要把多个分箱结果同时放进groupby(那样会做交叉维度统计,不是你要的独立分箱计数),下面两种写法都可以高效实现需求,尤其适合多列批量分箱统计的场景:
方案1:二值标识+分组求和(二分类分箱首选,性能最高)
先把每个分箱判定逻辑转成0/1标识列,再按A列分组求和即可,逻辑直白性能好:
import pandas as pd df = pd.DataFrame({ 'A': [1,1,2,2,3,3,3], 'B': [1,3,1,3,1,2,1], 'C': [1,3,5,3,7,7,1]}) # 生成分箱标识列 df['B_bin1'] = (df['B'] < 3).astype(int) df['B_bin2'] = (df['B'] >= 3).astype(int) df['C_bin1'] = (df['C'] < 5).astype(int) df['C_bin2'] = (df['C'] >= 5).astype(int) # 分组聚合得到结果 result = df.groupby('A', as_index=False)[['B_bin1','B_bin2','C_bin1','C_bin2']].sum()
运行结果完全匹配预期:
A B_bin1 B_bin2 C_bin1 C_bin2 0 1 1 1 2 0 1 2 1 1 1 1 2 3 3 0 1 2
方案2:配置化批量处理(多列/多区间分箱首选,易维护)
如果需要分箱的列很多,或者分箱区间不止2个,可以把分箱规则写成配置字典,批量生成哑变量后聚合,不需要写重复代码:
# 统一配置所有列的分箱规则、区间、输出列名,新增列直接加配置即可 bin_config = { 'B': {'bins': [0,2,10], 'labels': ['B_bin1','B_bin2']}, 'C': {'bins': [0,4,10], 'labels': ['C_bin1','C_bin2']} } dummy_cols = [] for col, cfg in bin_config.items(): # 对单列做分箱,转成哑变量矩阵 cut_result = pd.cut(df[col], bins=cfg['bins'], labels=cfg['labels']) dummy_cols.append(pd.get_dummies(cut_result)) # 拼接分组键和所有哑变量列,分组求和 result = pd.concat([df[['A']], *dummy_cols], axis=1).groupby('A', as_index=False).sum()
这个方案不管有多少待统计列、每个列分多少个区间,都只需要修改配置字典即可,不需要写重复的merge、unstack逻辑,性能也远高于逐表合并。
补充:NamedAgg写法
pd.NamedAgg也可以实现需求,但列多的时候写起来比较冗余,适合列少的场景:
result = df.groupby('A', as_index=False).agg( B_bin1 = ('B', lambda x: (x < 3).sum()), B_bin2 = ('B', lambda x: (x >= 3).sum()), C_bin1 = ('C', lambda x: (x < 5).sum()), C_bin2 = ('C', lambda x: (x >= 5).sum()) )
注意:不要把多个分箱结果同时传入
groupby,这种写法会计算多维度交叉的计数,也就是你看到的多层索引结果,和「每列独立分箱计数」的需求逻辑不符。
内容的提问来源于stack exchange,提问作者d_frEak
相关产品推荐
相关产品推荐

