如何按数字接近程度对列表分组?现有方法失效求优化方案
问题:按数字接近程度分组
给定数字列表:
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即可),然后按以下步骤操作:
- 对原列表升序排序
- 从第一个元素开始,把和当前组基准元素(组内第一个元素)差值在阈值内的元素归为一组,超过阈值就新建一组
代码实现:
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
相关产品推荐
相关产品推荐

