Python Pandas动态区间分组统计问题求助
解决Pandas动态区间分组统计问题
这需求我之前处理过,刚好可以用Pandas的分组+动态区间映射来实现,完全支持增删区间自动调整结果列,下面给你具体的实现步骤和代码:
步骤1:构造示例数据
先把你给出的示例数据用Pandas构造出来,方便后续演示:
import pandas as pd # 原始数据 df = pd.DataFrame({ 'A': ['P1', 'P1', 'P2', 'P2', 'P1', 'P1', 'P1'], 'B': ['P2', 'P2', 'P2', 'P1', 'P3', 'P3', 'P3'], 'val': [12, 14, 18, 17, 15, 16, 13] }) # 自定义区间配置 bins_df = pd.DataFrame({ 'MIN': [12, 13, 16], 'MAX': [12, 15, 17] })
步骤2:动态生成区间标签与映射逻辑
这里的核心是动态适配区间配置,不管你增删多少区间,代码都不用改:
# 将区间转换为元组列表,同时生成对应的列名(比如V_12_12) bins = list(zip(bins_df['MIN'], bins_df['MAX'])) bin_labels = [f'V_{min_val}_{max_val}' for min_val, max_val in bins] # 别忘了加上"其他值"的列名 bin_labels.append('V_OTHERS') # 定义函数:判断每个val属于哪个区间 def get_bin_label(val): for (min_val, max_val), label in zip(bins, bin_labels[:-1]): if min_val <= val <= max_val: return label # 不属于任何定义区间的,归为OTHERS return 'V_OTHERS' # 给原始数据添加区间标签列 df['bin_label'] = df['val'].apply(get_bin_label)
步骤3:分组统计并转换为目标格式
接下来按A、B分组,统计每个区间的数量,再转换成你需要的宽表格式:
# 分组统计每个区间的数量,unstack把标签转为列,fill_value=0填充空值 count_result = df.groupby(['A', 'B', 'bin_label']).size().unstack(fill_value=0) # 确保所有区间列都存在(比如某个分组没有对应区间的数据,也要显示0) for label in bin_labels: if label not in count_result.columns: count_result[label] = 0 # 调整列的顺序,和区间定义的顺序一致,最后保留V_OTHERS count_result = count_result[bin_labels] # 重置索引,把A、B从索引变回普通列 final_result = count_result.reset_index() print(final_result)
运行后输出的结果和你期望的完全一致:
A B V_12_12 V_13_15 V_16_17 V_OTHERS 0 P1 P2 1 1 0 0 1 P1 P3 0 2 1 0 2 P2 P1 0 0 1 0 3 P2 P2 0 0 0 1
动态调整区间的说明
如果需要增删区间,只需要修改bins_df即可,比如新增一个MIN=18, MAX=20的区间,代码不需要做任何改动,结果会自动新增V_18_20列;删除某个区间的话,结果里对应的列也会消失,完全满足你的动态调整需求。
内容的提问来源于stack exchange,提问作者user19725009
相关产品推荐
相关产品推荐

