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

如何实现数据分类?基于距离计算的Python聚类代码问题求解

问题核心原因

你当前要实现的是简易K-means聚类逻辑,无法在不修改原始数据的前提下完成分组的核心问题是没有做数据隔离:代码试图通过嵌套遍历原始点列表直接标记归属,既没有独立存储分组映射关系,还混杂了大量无意义的索引自增逻辑,很容易在遍历过程中误改原始坐标值,且距离计算结果没有对应存储,根本无法完成正确的分组归类。

实现思路

全程保持原始点列表只读,所有分组相关的操作全部在独立变量中完成:

  • 原始坐标点存储后不做任何增删改操作,从结构上避免原始值被改动
  • 随机选出的初始聚类中心点单独存为独立列表,和原始点列表完全隔离
  • 遍历每个原始点时,计算它到所有中心点的距离,记录距离最小的中心点对应分组编号
  • 分组结果单独存储,仅把点的引用加入对应分组,不修改原始点本身的数值
可直接运行的优化代码
from random import sample
import math

# 原始点列表,初始化后全程只读
points = []
group_count = int(input("How many groups of data: "))
point_count = int(input("How many data points would you like to enter: "))

for _ in range(point_count):
    x_val = int(input("X-value:"))
    y_val = int(input("Y-value:"))
    points.append((x_val, y_val))  # 用不可变元组存储原始坐标,从语法层面禁止误修改

# 随机选取初始中心点,独立存储不关联原始列表的修改逻辑
init_center_idx = sample(range(point_count), group_count)
centers = [points[idx] for idx in init_center_idx]

# 分组结果独立存储,不改动原始points
group_result = [[] for _ in range(group_count)]

# 遍历所有点完成归类
for p in points:
    min_distance = float('inf')
    target_group = 0
    # 计算当前点到每个中心点的距离,找最近的组
    for g_idx, center_p in enumerate(centers):
        # math.hypot直接计算欧氏距离,比手动写平方开根号更简洁
        current_dist = math.hypot(p[0] - center_p[0], p[1] - center_p[1])
        if current_dist < min_distance:
            min_distance = current_dist
            target_group = g_idx
    # 仅向分组结果中添加点,原始points无任何改动
    group_result[target_group].append(p)

# 验证输出
print("原始输入点列表(未作任何修改):", points)
for idx, group in enumerate(group_result):
    print(f"分组{idx+1} | 中心点坐标:{centers[idx]} | 组内点位:{group}")
关键优化点
  • 原始坐标用不可变元组存储,从语法层面杜绝了原始值被意外修改的可能,不需要额外加防护逻辑
  • 去掉了原有代码中d、c这类无意义的全局自增索引变量,避免索引越界、计数错位的bug
  • 原始点列表全程只做遍历读取,没有任何赋值、修改操作,100%保留用户输入的原始值
  • 中心点、分组结果全部用独立变量存储,和原始数据完全隔离,调整分组逻辑时不会影响原始数据
  • 距离计算直接用math.hypot实现,代码更简洁,计算效率更高

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.26 14:18:18