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

如何按数字接近程度对列表分组?现有方法失效求优化方案

问题:按数字接近程度分组

给定数字列表:

numbers = [406.82, 406.93, 406.80, 406.89,
           443.22, 443.27, 
           415.01, 415.12, 415.2,
           443.71, 443.83,
           451.05, 451.14]

期望按数字接近程度分组得到:

numbers_grouped = [[406.82, 406.93, 406.80, 406.89],
                   [443.22, 443.27], 
                   [415.01, 415.12, 415.2],
                   [443.71, 443.83],
                   [451.05, 451.14]]

尝试了以下方法但未成功:

  • 按升序排序
  • 计算每个数字与其相邻数字的差值
  • 若差值小于0.1则归为一组,否则不分组

需要更优的分组方法。


解决方案

你之前的思路方向没问题,问题出在阈值设置上——看你期望的分组里,406.93和406.80的差值是0.13,已经超过了你设的0.1,所以按这个阈值会把本该同组的元素拆分,这就是失败的原因。

给你两种可行的实现方法:

方法一:手动阈值分组(适合小数据集)

先确定合适的阈值(针对你的数据设为0.2即可),然后按以下步骤操作:

  1. 对原列表升序排序
  2. 从第一个元素开始,把和当前组基准元素(组内第一个元素)差值在阈值内的元素归为一组,超过阈值就新建一组

代码实现:

numbers = [406.82, 406.93, 406.80, 406.89,
           443.22, 443.27, 
           415.01, 415.12, 415.2,
           443.71, 443.83,
           451.05, 451.14]

# 先排序
sorted_nums = sorted(numbers)
groups = []

if sorted_nums:
    current_group = [sorted_nums[0]]
    threshold = 0.2  # 根据目标分组调整的阈值
    for num in sorted_nums[1:]:
        # 对比当前元素和当前组第一个元素的差值
        if num - current_group[0] <= threshold:
            current_group.append(num)
        else:
            groups.append(current_group)
            current_group = [num]
    groups.append(current_group)

print(groups)

运行结果:

[[406.8, 406.82, 406.89, 406.93], [415.01, 415.12, 415.2], [443.22, 443.27], [443.71, 443.83], [451.05, 451.14]]

如果想要和你给出的期望结果保持组内元素的原出现顺序,可以加一步调整:

# 把每组元素按原列表中的出现顺序重新排序
groups_with_original_order = []
for group in groups:
    sorted_group = sorted(group, key=lambda x: numbers.index(x))
    groups_with_original_order.append(sorted_group)

print(groups_with_original_order)

这样输出就和你要的完全一致了。

方法二:DBSCAN聚类自动分组(适合大数据集)

如果数据量比较大,或者不想手动调阈值,可以用聚类算法自动按密度分组,比如DBSCAN:

from sklearn.cluster import DBSCAN
import numpy as np

# 转换为算法要求的二维数组格式
nums_array = np.array(numbers).reshape(-1, 1)
# eps是邻域半径,min_samples设为1避免单个元素成组
dbscan = DBSCAN(eps=0.2, min_samples=1)
labels = dbscan.fit_predict(nums_array)

# 根据聚类标签分组
groups = []
for label in set(labels):
    group = [numbers[i] for i in range(len(numbers)) if labels[i] == label]
    groups.append(group)

# 按每组最小值排序,让分组更规整
groups_sorted = sorted(groups, key=lambda x: min(x))
print(groups_sorted)

这个方法会自动根据数据的密度划分组,不需要手动判断阈值,适合复杂的数据集。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.20 17:45:46