我有一个包含大约1000行的数据框和一个名为calc_value
的列。大约10%的calc_value
值为0.
我想根据calc_value
为数据框中的每一行分配一个百分位数。但是,由于非唯一的bin边缘,使用qcut
会给我一个错误:
df['percentile'] = pd.qcut(df.calc_value, 100, labels=False)
它抛出了这个错误:
ValueError: Bin edges must be unique: array([ 0. , 0. , 0. , 0. , 0. ,
0. , 0. , 0. , 0. , 0.00182298,
0.0030689 , 0.00394358, 0.00479595, 0.00547278, 0.0060241 ,
0.0066023 , 0.00712708, 0.00760456, 0.00816327, 0.00862069,
0.00917431, 0.00959605, 0.01010101, 0.01058201, 0.01094173,
0.01136364, 0.01185771, 0.01230635, 0.01282051, 0.01324503,
0.01369863, 0.0140051 , 0.01447252, 0.01489758, 0.01528912,
0.01569299, 0.01612903, 0.01657785, 0.01699717, 0.01750547,
0.017924 , 0.01840491, 0.01889004, 0.0193326 , 0.01984022,
0.0202292 , 0.02076186, 0.02118433, 0.02173913, 0.02217742,
0.02265831, 0.0231333 , 0.02369503, 0.02422837, 0.02482127,
0.02551955, 0.0260492 , 0.02659574, 0.02714932, 0.0276922 ,
0.02816901, 0.02882712, 0.02941176, 0.03020364, 0.0308642 ,
0.03141361, 0.03209368, 0.03278689, 0.03349899, 0.03433476,
0.03508136, 0.03571429, 0.03645665, 0.03703704, 0.03768171,
0.03852266, 0.0392761 , 0.04021883, 0.04130278, 0.04222222,
0.04316547, 0.04416658, 0.04528395, 0.04630852, 0.04761905,
0.04908678, 0.05062638, 0.05230894, 0.05421013, 0.05604617,
0.05833204, 0.06024096, 0.06314209, 0.06598985, 0.06975211,
0.07406687, 0.08098836, 0.08905262, 0.10144029, 0.12169944,
0.48 ])
如果bin边缘不是唯一的,我不在乎,我想继续并为每一行分配一个等值百分位0
的零值。然后从那里继续,在这种情况下下一个百分位为10
。
如何忽略此错误并继续?
答案 0 :(得分:1)
看起来scipy.stats.rankdata
完全符合您的要求,包括对领带休息的良好控制
方法:str,可选 用于将排名分配给绑定元素的方法。选项包括'average','min','max','dense'和'ordinal'。
如,
from scipy.stats import rankdata
>>> rankdata([0, 2, 3, 2], method='min')
array([ 1., 2., 4., 2.])
因此,在您的情况下,您可以使用
from scipy.stats import rankdata
df['percentile'] = rankdata(df.calc_value.values, method=<whatever you want>) / len(df)
(注意我们如何除以DataFrame的长度)。
答案 1 :(得分:0)
我相信pd.qcut()需要一个整数作为第二个arg,这样数据行数/ int也是一个int。所以你要么必须添加空行以便稍后删除它们,要么找到最接近的int:
div = 100
while True:
if not 968%div:
break
else:
div -= 1
print div