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

如何分割numpy坐标点列表的两类点簇并分别计算均值

问题背景

现有存储二维坐标点对的numpy数组,需要对空间近邻的点分组计算簇均值,固定返回2个簇的中心点。

第一组测试样例

输入点集:

[[214,295], [215, 294], [229, 226], [229, 227]]

当前基于Z-score的实现输出为:

[[222.0, 260.5], [214.0, 295.0], [229.0, 226.0]]

预期输出为两组近邻点各自的均值:

  • 近邻组1([214,295]、[215,294])均值:[214.5, 294.5]
  • 近邻组2([229,226]、[229,227])均值:[229.0, 226.5]
    要求最终固定返回2个点,不出现3个及以上结果,需要确认是否要重新调整Z-score计算逻辑。

第二组测试样例

输入点集:
[[95, 132], [96, 132], [94, 133], [134, 239], [95, 131]]
当前实现输出为:

[[ 95. 132.], [134. 239.]]

需求:当[134,239]点位附近聚集大量点时,需要更鲁棒的双点簇分割方法。

现有实现代码

import numpy as np
from scipy import stats

tempList = np.array([[214,295], [215, 294],[229, 226], [229, 227]])

z= stats.zscore(tempList, axis=0)
z = list([abs(x)<1 and abs(y)<1 for x,y in z])

newList = tempList[[not x for x in z]]

tempList = tempList[z]

newList = np.concatenate([[tempList.mean(axis=0)], newList])
print(newList)
解决方案

不需要调整Z-score计算逻辑,Z-score本身是基于单维度全局分布的异常值过滤方法,完全不感知二维空间中点的距离邻近关系,第一组数据出错的原因是全局均值刚好落在两个点簇的中间位置,被Z-score判定为正常点,最终输出了多余的中心点。
针对固定分割2个点簇的需求,直接使用指定簇数为2的K-Means聚类即可,该方法基于空间距离划分簇,对两个簇点数差异较大、点聚集的场景鲁棒性远高于全局Z-score过滤。

修正后实现代码

import numpy as np
from sklearn.cluster import KMeans

# 测试第一组数据
tempList1 = np.array([[214,295], [215, 294],[229, 226], [229, 227]])
kmeans = KMeans(n_clusters=2, n_init=10, random_state=42)
kmeans.fit(tempList1)
print("第一组簇中心:\n", kmeans.cluster_centers_)
# 输出 [[214.5 294.5] [229.  226.5]],完全匹配预期结果

# 测试第二组数据
tempList2 = np.array([[95, 132], [96, 132], [94, 133], [134, 239], [95, 131]])
kmeans.fit(tempList2)
print("第二组簇中心:\n", kmeans.cluster_centers_)
# 输出 [[ 95. 132.] [134. 239.]],和现有正确结果一致

如果场景中存在远离两个主簇的极端离群点,可以在聚类前增加一层基于距离的离群点过滤;如果无法100%确定点簇数量固定为2,也可以替换为DBSCAN密度聚类,自动识别高密度点簇后取规模最大的2个簇计算均值。但固定返回2个簇的场景下,指定簇数的K-Means是实现最简单、效果最稳定的方案。


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

相关产品推荐
方舟 Agent Plan

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

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