Pandas qcut返回整数分箱结果与Excel QUARTILE.EXC不一致如何解决?
问题原因
- 输出整数分箱的直接原因是你在调用
pd.qcut时主动指定了labels=range(1,n_bins+1)参数:该参数会强制将每个分箱的返回值替换为你预设的1、2、3、4整数标签,自然不会返回区间类的非整数结果。 - 分箱结果和Excel
QUARTILE.EXC()不一致的核心原因是二者默认的分位数计算规则不同:ExcelQUARTILE.EXC()采用的分位数位置计算公式为位置 = k*(n+1)/4,和pandas默认的线性插值分位数计算逻辑有差异。
调整方案
你可以按以下步骤修改代码,得到和Excel规则一致的非整数区间分箱结果:
- 移除
labels参数,让qcut默认返回区间对象作为分箱标识 - 给
qcut指定method='weibull'参数,匹配ExcelQUARTILE.EXC()的分位数计算规则
修改后的参考代码如下:
import pandas as pd data = {0: 2.75, 1: 2.875, 2: 3.5, 3: 3.875, 4: 3.125, 5: 2.25, 6: 2.125, 7: 3.375, 8: 3.75, 9: 1.875, 10: 3.125, 11: 2.625, 12: 1.25, 13: 2.625, 14: 2.25, 15: 3.125, 16: 3.375, 17: 2.25, 18: 2.25, 19: 3.125, 20: 3.375, 21: 2.5, 22: 3.375, 23: 3.5, 24: 3.125, 25: 3.0, 26: 2.125, 27: 3.125, 28: 2.375, 29: 2.375, 30: 2.75, 31: 3.0, 32: 2.625, 33: 2.0, 34: 2.75, 35: 3.25, 36: 3.0, 37: 1.5, 38: 3.5, 39: 2.375, 40: 3.375, 41: 2.625, 42: 3.0, 43: 2.5, 44: 2.625, 45: 2.875, 46: 2.25, 47: 2.5, 48: 1.125, 49: 1.625, 50: 1.375, 51: 2.125, 52: 1.625, 53: 2.125, 54: 1.0, 55: 1.5, 56: 1.25, 57: 3.125, 58: 1.125, 59: 1.75} df = pd.Series(data).to_frame('values') n_bins = 4 # 移除自定义标签,指定分位数计算方法匹配Excel规则 df['qcutbins'] = pd.qcut(df['values'], q=n_bins, method='weibull') # 查看分箱统计结果 df.groupby(['qcutbins'])['values'].describe()[['min','max']].sort_values(by='max').reset_index(drop=True)
如果需要更灵活的控制分箱边界,也可以手动计算符合Excel规则的分位数点后调用pd.cut分箱:
# 手动计算四分位点 quantiles = df['values'].quantile([0.25,0.5,0.75], method='weibull') # 构造分箱边界,加极小值避免边界值被漏判 bins = [df['values'].min() - 1e-9] + quantiles.tolist() + [df['values'].max() + 1e-9] df['cutbins'] = pd.cut(df['values'], bins=bins)
内容的提问来源于stack exchange,提问作者mikelowry
相关产品推荐
相关产品推荐

