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

纯Python实现聚类:按欧氏距离将数据点分配至最近质心

Kmeans单点分配实现方案

你现有代码存在两个核心问题,导致无法完成聚类:

  • 聚类列表初始化错误:[[]] * 6 会生成6个指向同一内存地址的空列表,修改任意一个子列表所有子列表都会同步变化;且你只有4个质心,不需要初始化6个子列表。
  • 缺少距离比较、匹配最近质心的逻辑:当前代码仅把所有距离追加到总列表中,没有关联距离和对应质心的序号,也没有筛选最小距离。

实现逻辑

按照Kmeans的簇分配步骤,按以下流程写即可:

  1. 为每个质心创建独立的空列表,作为对应簇的存储容器,子列表数量和质心数量完全一致。
  2. 逐个遍历数据点,计算当前点到每一个质心的欧氏距离,把所有距离按质心顺序存入临时列表。
  3. 找到临时距离列表中最小值对应的索引,该索引就是当前点所属簇的序号。
  4. 把当前点追加到对应序号的簇列表中,所有点遍历完成后返回聚类结果即可。

注:比较距离大小时可以省略math.sqrt()计算,因为平方根是单调递增运算,不影响距离大小的判断结果,能省一点计算量;加上也完全不影响结果正确性。


修正后可直接运行的代码

import math

def cluster_mydata(centroids, points):
    # 为每个质心初始化独立的空簇,索引和质心顺序一一对应
    clusters = [[] for _ in range(len(centroids))]
    for point in points:
        # 记录当前点到所有质心的距离
        distance_list = []
        for centroid in centroids:
            euclidean_dist = math.sqrt(
                (point[0] - centroid[0]) ** 2 
                + (point[1] - centroid[1]) ** 2
            )
            distance_list.append(euclidean_dist)
        # 找到距离最近的质心对应的索引
        nearest_idx = distance_list.index(min(distance_list))
        # 将点划入对应簇
        clusters[nearest_idx].append(point)
    return clusters

测试示例

用你给出的样例数据测试:

if __name__ == "__main__":
    sample_centroids = [[12,3],[0,-8],[-28,20],[1,1]]
    sample_points = [(31,3),(10,9),(1,0),(-2,-5)]
    print(cluster_mydata(sample_centroids, sample_points))

输出结果为:

[[(31, 3), (10, 9)], [(-2, -5)], [], [(1, 0)]]

结果完全符合要求:第1个子列表存距离第1个质心最近的点,第2个对应第2个质心,以此类推,示例中没有点距离第3个质心(-28,20)最近,因此对应子列表为空。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.29 23:39:14