带容差的元素计数:合并近似值并累加计数
带容差的近似数值计数合并实现
我有一个长数值列表(简化版如下):
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
相关产品推荐
相关产品推荐

