问题描述
我有一个包含 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,))
问题是,在某些列上,它给了我所有的桶,而在其他列上,它只给了我几个:
有没有办法确保它创建所有存储桶?我可能在这里遗漏了一些东西。
解决方法
如果您想确保在“存储桶”之间获得相似的分布,您可能想尝试使用 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
无法生成所需数量的分位数(例如,因为没有足够的值来创建分位数),传递比分位数更多的标签,您将得到一个例外。