Pandas中相同Metric值对应多个分位数标签的问题排查
问题:相同Metric值被分配多个分位数标签的原因
拥有一个Metric列,想要创建新列标记每个Metric值所属的分位数,但发现相同的Metric值被分配了多个分位数标签,不符合预期。以Metric_Quantile_2列为例,相同的5.0值既有Quantile_2_1标签,也有Quantile_2_2标签。
数据示例
| Metric |
|---|
| 5.0 |
| 5.0 |
| 6.0 |
| 5.0 |
| NaN |
| 5.0 |
| 5.0 |
| 2.0 |
| 6.0 |
| 3.0 |
| NaN |
| 2.0 |
| 5.0 |
| 5.0 |
| 5.0 |
| 2.0 |
使用的代码
var_metric = ['Metric'] # Quantile range I am interested in creating labels for quantiles_list = [2, 3, 4, 5] # Quantile labels quantile_2_labels = ['Quantile_2_1','Quantile_2_2'] quantile_3_labels = ['Quantile_3_1','Quantile_3_2','Quantile_3_3'] quantile_4_labels = ['Quantile_4_1','Quantile_4_2','Quantile_4_3','Quantile_4_4'] quantile_5_labels = ['Quantile_5_1','Quantile_5_2','Quantile_5_3','Quantile_5_4','Quantile_5_5'] quantiles_labels_list = [quantile_2_labels, quantile_3_labels, quantile_4_labels, quantile_5_labels] # Loops for creating label columns for metric in var_metric: for quantile, labels in zip(quantiles_list, quantiles_labels_list): df[f'{metric}_Quantile_{quantile}'] = pd.qcut(df[metric].astype('Int64').rank(method='first'), q=quantile, labels=labels, retbins=False)
原因分析
- 核心问题出在
rank(method='first')操作:当对相同的Metric值(比如多个5.0)使用method='first'排名时,pandas会按照元素在DataFrame中的出现顺序,给每个相同值分配唯一且递增的排名。这导致原本相同的5.0被赋予了不同的排名数值。 - 后续的
pd.qcut基于这些排名值划分分位数,不同的排名自然会被分到不同的分位数区间,最终相同的Metric值就得到了不同的分位数标签。 astype('Int64')转换仅将浮点数转为可空整数,对该问题无影响,关键是排名方法的选择。
若要让相同Metric值被分到同一个分位数,可采取以下方式:
- 去掉
rank操作,直接用原始Metric值执行qcut(注意处理NaN,可使用dropna或qcut的na_position参数); - 若必须使用排名,将
method='first'改为method='min'或method='max',确保相同值获得相同排名,后续qcut就能将它们归入同一分位数。
内容的提问来源于stack exchange,提问作者jim_jones
相关产品推荐
相关产品推荐

