You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

pandas如何实现带容差(tolerance)的数值排名功能

pandas 带自定义容差的排名实现方案

pandas 原生 rank() 方法没有内置容差阈值参数,无法直接实现「差值小于等于指定阈值视为相等、取平均名次」的需求,可以通过排序后按相邻差值分组的方式实现,逻辑稳定且适配任意容差值。


实现思路

  • 先对目标序列排序,保留值与原索引的对应关系
  • 计算相邻元素的差值,相邻差值超过容差阈值时划分新的分组,差值在阈值内的连续值归为同一组
  • 每个分组的排名取该组覆盖名次的平均值,最后映射回原序列的索引顺序即可

可直接复用的代码

import pandas as pd

def rank_with_tolerance(series, tol=0.01):
    # 对序列排序
    sorted_vals = series.sort_values()
    # 计算相邻值差值,超过容差则标记为新分组起点
    adjacent_diff = sorted_vals.diff().abs()
    group_mark = (adjacent_diff > tol).cumsum()
    # 计算每个分组对应的平均名次
    group_size = group_mark.value_counts().sort_index()
    group_end_rank = group_size.cumsum()
    group_start_rank = group_end_rank - group_size + 1
    group_avg_rank = (group_start_rank + group_end_rank) / 2
    # 映射回原序列索引顺序
    return group_mark.map(group_avg_rank).reindex(series.index)


# 测试示例
ex = pd.Series([16.52,19.95,16.15,22.77,20.53,19.96])
result = rank_with_tolerance(ex, tol=0.01)
print(result)

运行结果

和需求给出的期望输出完全一致:

0    2.0
1    3.5
2    1.0
3    6.0
4    5.0
5    3.5
dtype: float64

注意事项

  • 该实现采用连续相邻值判断逻辑,符合常规容差相等的判断规则:例如序列[1, 1.01, 1.02]在容差0.01下会被归为同一组,不会因为首尾差值0.02超过容差就拆分。
  • 不要通过round()保留固定小数位的方式实现容差排名,该方法仅能适配小数位对齐的特殊容差场景,无法支持任意阈值(如容差0.03、0.5等),且容易出现边界值判断错误。
  • 如果需要使用其他排名规则(如取组内最小名次、最大名次),只需修改分组对应名次的计算逻辑即可。

内容的提问来源于stack exchange,提问作者Carlos Grohmann

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.26 09:54:27