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

带容差的元素计数:合并近似值并累加计数

带容差的近似数值计数合并实现

我有一个长数值列表(简化版如下):

ed = [ 0.52309  ,  3.1443  , 16.5789  , 24.0643  ,  9.70981 ,  1.71983 ,
       16.3453  , 14.1901  , 22.0353  ,  1.71983 , 15.0469  , 13.98    ,
       11.4753  , 32.7859  ,  9.7098  ,  6.36272 ,  3.2058  ,  1.46917 ,
        6.36271 , 11.5869  ,  1.72052 ,  6.32043 ,  1.72052 ,  1.72052 ,
        5.37679 ,  3.15279 ,  9.70979 ,  1.72052 ,  3.44035 ,  2.15729 ,
       12.0049  ]

用以下代码计数后:

from collections import Counter

cnt = Counter(ed)
edlist = [list(i) for i in cnt.items()]

得到的结果里存在近似值分组的问题,比如:

[[1.72052, 60], [1.71983, 34], [6.36271, 16], [9.7098, 14],[9.70979, 5], [0.52309, 3], [9.70981, 3]]

我需要在指定容差内把这些近似值的计数合并——比如把9.7098(计数14)、9.70981(计数3)、9.70979(计数5)的计数累加至该组内计数最高的项,最终得到:

[[1.72052, 60], [1.71983, 34], [6.36271, 16], [9.7098, 22], [0.52309, 3]]

了解分组和聚类的概念,但不知道怎么具体应用,需要实现带容差的元素计数并保留各值的出现次数统计。


解决方案

通过基于容差的聚类分组即可实现,核心逻辑是:先将计数后的项按数值排序,遍历过程中把差值在容差内的项归为一组,每组保留计数最高的数值作为代表,累加组内所有计数。

实现代码

from collections import Counter

def merge_approx_counts(counter, tolerance=1e-4):
    # 将Counter的键值对按数值排序,让近似值相邻
    sorted_items = sorted(counter.items(), key=lambda x: x[0])
    merged = []
    
    if not sorted_items:
        return merged
    
    # 初始化第一组:取第一个元素的数值、计数,记录组内最高计数的代表值
    current_val, current_count = sorted_items[0]
    max_count_in_group = current_count
    representative_val = current_val
    
    for val, count in sorted_items[1:]:
        # 判断当前值与组内代表值的差值是否在容差范围内
        if abs(val - representative_val) <= tolerance:
            current_count += count
            # 如果当前项计数更高,更新组的代表值
            if count > max_count_in_group:
                max_count_in_group = count
                representative_val = val
        else:
            # 超出容差,保存当前组并初始化新组
            merged.append([representative_val, current_count])
            current_val, current_count = val, count
            max_count_in_group = count
            representative_val = val
    # 保存最后一组数据
    merged.append([representative_val, current_count])
    
    # 按计数降序排序,与示例输出格式一致
    merged.sort(key=lambda x: x[1], reverse=True)
    return merged

# 测试示例
ed = [ 0.52309  ,  3.1443  , 16.5789  , 24.0643  ,  9.70981 ,  1.71983 ,
       16.3453  , 14.1901  , 22.0353  ,  1.71983 , 15.0469  , 13.98    ,
       11.4753  , 32.7859  ,  9.7098  ,  6.36272 ,  3.2058  ,  1.46917 ,
        6.36271 , 11.5869  ,  1.72052 ,  6.32043 ,  1.72052 ,  1.72052 ,
        5.37679 ,  3.15279 ,  9.70979 ,  1.72052 ,  3.44035 ,  2.15729 ,
       12.0049  ]

cnt = Counter(ed)
result = merge_approx_counts(cnt, tolerance=1e-4)
print(result)

代码说明

  • 排序处理:先对计数后的键值对按数值排序,确保近似值处于相邻位置,方便后续分组判断。
  • 容差判断:遍历过程中,若当前数值与组内代表值的差值在容差内,则累加计数,并更新组内计数最高的代表值。
  • 组的切换:遇到超出容差的数值时,保存当前组并初始化新组。
  • 自定义容差:可以根据需求调整tolerance参数,比如宽松合并用1e-3,严格合并用1e-5。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.04 05:25:16