如何为Pandas分组DataFrame的条目划分分位数区间?
问题描述
现有如下Pandas DataFrame:
import pandas as pd example = {'Player': ['A', 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'B', 'B', 'B', 'B', 'B', 'B', 'B', 'B', 'C', 'C', 'C', 'C', 'C', 'C', 'C', 'C'], 'wins': [2, 4, 4, 5, 6, 9, 13, 13, 15, 15, 14, 13, 11, 9, 9, 8, 8, 16, 19, 21, 14, 20, 19, 18]} df = pd.DataFrame(example)
需要新增一列quantile_bin,取值为1到10的整数,标识每个Player分组内wins值所属的分位数区间:1对应0-0.1分位数,2对应0.1-0.2分位数……10对应0.9-1.0分位数。
预期结果示例:
>>> df Player wins quantile_bin 0 A 2 1 1 A 4 2 2 A 4 2 3 A 5 5 4 A 6 6 5 A 9 8 6 A 13 10 7 A 13 10 8 B 15 10 9 B 15 10 10 B 14 9 11 B 13 6 12 B 11 5 13 B 9 2 14 B 9 2 15 B 8 1 16 C 8 1 17 C 16 3 18 C 19 7 19 C 21 10 20 C 14 2 21 C 20 9 22 C 19 7 23 C 18 5
解决方案
方法1:使用qcut结合groupby.transform(推荐)
直接利用Pandas内置的pd.qcut函数,通过groupby.transform实现分组内的分位数分箱,这是最简洁高效的方式:
def assign_quantile_bin(x): # 生成10个等频分位数区间,标签设为1到10 return pd.qcut(x, q=10, labels=range(1, 11), duplicates='drop') df['quantile_bin'] = df.groupby('Player')['wins'].transform(assign_quantile_bin)
q=10:将分组内数据分为10个等频区间,对应0-0.1到0.9-1.0的分位数范围labels=range(1,11):指定输出的箱编号为1到10duplicates='drop':处理因分组内重复值导致的分位点重复问题,避免报错
方法2:自定义magic_quantile_function
如果需要手动实现分箱逻辑,可以定义如下函数,通过groupby.apply调用:
def magic_quantile_function(x): # 计算分组内的10个分位点(0, 0.1, ..., 1.0) quantiles = x.quantile([i/10 for i in range(11)]) # 去掉重复分位点,避免分箱重叠 quantiles = quantiles.drop_duplicates() # 按分位点分箱,左闭右开,标签设为1到分箱数 bins = pd.cut(x, bins=quantiles, labels=range(1, len(quantiles)), include_lowest=True) # 转换为整数类型匹配预期格式 return bins.astype(int) # 应用到分组数据并赋值给新列 df['quantile_bin'] = df.groupby('Player')['wins'].apply(magic_quantile_function).reset_index(drop=True)
include_lowest=True:确保最小值被包含在第一个区间内- 手动去重分位点:避免因重复值导致的分箱逻辑错误
验证结果
执行上述任意一种方法后,输出的df会与示例中的预期结果一致。
内容的提问来源于stack exchange,提问作者gdol
相关产品推荐
相关产品推荐

