Python 具有非唯一箱边的qcut产生错误数量的分位数

Python 具有非唯一箱边的qcut产生错误数量的分位数,python,pandas,Python,Pandas,我有一个简单的方法来计算小数点: def输出十位数(型号,X,y,顺序='predictions'): 结果=pd.DataFrame(model.predict(X),index=X.index,columns=['predictions'])) 结果['actual']=y 结果['deciles']=pd.qcut(结果[顺序],10,标签=False,重复项='drop') 返回结果 如果我在预测的十分位数上使用它,一切都会正常工作: out=输出十位数(管道,X,y) out.gro

我有一个简单的方法来计算小数点:

def输出十位数(型号,X,y,顺序='predictions'):
结果=pd.DataFrame(model.predict(X),index=X.index,columns=['predictions']))
结果['actual']=y
结果['deciles']=pd.qcut(结果[顺序],10,标签=False,重复项='drop')
返回结果
如果我在预测的十分位数上使用它,一切都会正常工作:

out=输出十位数(管道,X,y)
out.groupby('deciles')[[['actual','predictions']]].mean()

这是大约9400张唱片上的记录

但是如果我试着得到我实际值的十分位数,我只得到7而不是10。这是因为我在此目标中的值约有一半为0:

out=output\u十分位数(管道,X,y,order='actual')
out.groupby('deciles')[[['actual','predictions']]].mean()

尽管存在大量独特的值,但仍然存在这种情况:

print(len(out['actual'].unique())
4593

这是违反直觉的——它几乎就像是在丢弃整个箱子,而不仅仅是一些重复的值。但如果我将duplicates设置更改为“raise”,它将抛出:

ValueError:Bin边必须唯一:数组([-4.60517019,0,0,0,0,0,0,0,0,0,0,, 3.47630251, 8.40045698, 10.11776099, 11.46706716, 12.86027487, 17.7007044])


如果给定非唯一的bin边,当我指的是十分位数时,如何得到十分位数?

您可能正在寻找一种自己构造“分位数”的方法。您可以通过排序然后使用整数除法来定义组来完成此操作

我将在0处创建质量过大的数据,这样
pd.qcut
将抱怨重复

import pandas as pd
import numpy as np

np.random.seed(410012)
s = pd.Series(np.random.normal(0, 4, 1000))
s = pd.concat([s, pd.Series([0]*500)])
s = s.to_frame('vals')

N = 10
s = s.sort_values('vals')
s['q'] = np.arange(len(s)) // (len(s)/N)

有了q,我们现在得到了10个垃圾箱

s.groupby('q').describe()
#      vals                                                          
#     count    mean     std      min     25%     50%     75%      max
#q                                                                   
#0.0  150.0 -6.5934  1.9208 -12.6041 -7.7703 -6.1546 -5.1073  -4.3421
#1.0  150.0 -3.1922  0.5621  -4.3287 -3.6605 -3.1293 -2.7377  -2.2718
#2.0  150.0 -1.4932  0.4203  -2.2561 -1.8196 -1.5262 -1.1364  -0.7451
#3.0  150.0 -0.1831  0.2400  -0.7425 -0.3371 -0.0110  0.0000   0.0000
#4.0  150.0  0.0000  0.0000   0.0000  0.0000  0.0000  0.0000   0.0000
#5.0  150.0  0.0000  0.0000   0.0000  0.0000  0.0000  0.0000   0.0000
#6.0  150.0  0.0238  0.0678   0.0000  0.0000  0.0000  0.0000   0.2856
#7.0  150.0  1.1555  0.4833   0.3353  0.7615  1.1837  1.5819   1.9513
#8.0  150.0  2.9430  0.6016   1.9660  2.4385  2.9665  3.4764   4.0277
#9.0  150.0  6.1692  1.6616   4.0336  4.8805  5.8176  6.9019  12.3437
不与问题值重叠的箱子是相同的,但0为边的两个箱子是不同的(因为它们已折叠)

s.groupby(pd.qcut(s['vals'], 10, duplicates='drop'))['vals'].describe()
#                              count    mean     std      min     25%     50%     75%      max
#vals                                                                                         
#(-12.604999999999999, -4.33]  150.0 -6.5934  1.9208 -12.6041 -7.7703 -6.1546 -5.1073  -4.3421
#(-4.33, -2.259]               150.0 -3.1922  0.5621  -4.3287 -3.6605 -3.1293 -2.7377  -2.2718
#(-2.259, -0.743]              150.0 -1.4932  0.4203  -2.2561 -1.8196 -1.5262 -1.1364  -0.7451
#(-0.743, 0.0]                 576.0 -0.0477  0.1463  -0.7425  0.0000  0.0000  0.0000   0.0000
#(0.0, 0.301]                   24.0  0.1490  0.1016   0.0024  0.0457  0.1497  0.2485   0.2856
#(0.301, 1.954]                150.0  1.1555  0.4833   0.3353  0.7615  1.1837  1.5819   1.9513
#(1.954, 4.028]                150.0  2.9430  0.6016   1.9660  2.4385  2.9665  3.4764   4.0277
#(4.028, 12.344]               150.0  6.1692  1.6616   4.0336  4.8805  5.8176  6.9019  12.3437