Pandas 分位数函数未返回正确数量的给定分位数

问题描述

我有一个包含 2,000 多条记录的数据框,其中包含多个具有各种余额的列。根据我想将其分配给存储桶的余额金额。

尝试将每个余额列拆分为一个分位数并具有以下存储分区 0.1,0.2,0.3,0.4,0.5,0.6,0.7,0.8,0.9 具体而言,将余额转换为以下存储分区:前 10%、前 20%、前 30% 等...>

如果我理解正确,只要有超过 10 条记录,它就应该根据线性插值将每条记录存储在一个百分位中。

所以我运行以下:

score_quantiles =  df.quantile(q=[0.1,0.9])
score_quantiles.to_dict()



# Arguments (x = value,p = field (i.e bal 1,bal2,bal3),d = score_quantiles)

def dlpscore(x,p,d):
    if pd.isnull(x) == True:
        return 0 
    elif int(x) == 0:
        return 0
    elif x <= d[p][0.1]:
        return 1
    elif x <= d[p][0.2]:
        return 2
    elif x <= d[p][0.3]: 
        return 3
    elif x <= d[p][0.4]: 
        return 4
    elif x <= d[p][0.5]: 
        return 5
    elif x <= d[p][0.6]: 
        return 6
    elif x <= d[p][0.7]: 
        return 7
    elif x <= d[p][0.8]: 
        return 8
    elif x <= d[p][0.9]: 
        return 9
    else:
        return 10



df['score_BAL1'] = df['bal1'].apply(dlpscore,args=('bal1',score_quantiles,))




问题是,在某些列上,它给了我所有的桶,而在其他列上,它只给了我几个:

enter image description here

enter image description here

有没有办法确保它创建所有存储桶?我可能在这里遗漏了一些东西。

解决方法

如果您想确保在“存储桶”之间获得相似的分布,您可能想尝试使用 pandas qcut 函数。 full documentation is here

要在您的代码中使用它并获得十分位数,您可以这样做

n_buckets=10
df['quantile'] = pd.qcut(df['target_column'],q=n_buckets)

如果你想应用一个特定的标签,你可以做这样的事情

n_buckets=10
df['quantile'] = pd.qcut(df['target_column'],q=n_buckets,labels=range(1,n_buckets+1))

PS: 请注意,对于后一种情况,如果 qcut 无法生成所需数量的分位数(例如,因为没有足够的值来创建分位数),传递比分位数更多的标签,您将得到一个例外。