这是我previous问题的延续。我现在有一个欧几里德空间中的坐标排序列表。我希望以这样的方式平均最近的坐标,即聚类起作用,即整个聚类被平均并返回欧几里德空间中的一个单点。所以,例如下面的列表
a = [[ 42, 206],[ 45, 40],[ 45, 205],[ 46, 41],[ 46, 205],[ 47, 40],[ 47, 202],[ 48, 40],[ 48, 202],[ 49, 38]]
将返回avg_coordinates = [[47.0, 39.8], [45.6, 204.0]]
。这是通过平均前5个最近点(或簇)然后最后5个最近点来完成的。现在我正在使用渐变方法,即我循环遍历所有坐标,并且在梯度高于某个设置阈值的任何地方,然后我认为它是另一个点集群(因为列表已经排序)。但是当我在梯度公式gradient = (y2-y1)/(x2-x1)
中有更高的分母然后分子时会出现问题,它会返回一个小于阈值的值。所以逻辑上我做错了。这样做有什么好的建议吗?请注意我不想应用群集。
答案 0 :(得分:3)
这是一种方法 -
thresh = 100 # Threshold for splitting, heuristically chosen for given sample
# Lex-sort of coordinates
b = a[np.lexsort(a.T)]
# Interval indices that partition the clusters
diff_idx = np.flatnonzero(np.linalg.norm(b[1:] - b[:-1],axis=1) > thresh)+1
idx = np.hstack((0, diff_idx, b.shape[0]))
sums = np.add.reduceat(b, idx[:-1])
counts = idx[1:] - idx[:-1]
out = sums/counts.astype(float)[:,None]
示例输入,输出 -
In [141]: a
Out[141]:
array([[ 42, 206],
[ 45, 40],
[ 45, 205],
[ 46, 41],
[ 46, 205],
[ 47, 40],
[ 47, 202],
[ 48, 40],
[ 48, 202],
[ 49, 38]])
In [142]: out
Out[142]:
array([[ 47. , 39.8],
[ 45.6, 204. ]])
答案 1 :(得分:2)
如果您乐意使用库而不是重新实现群集,可以使用scikit-learn中的k-means: http://scikit-learn.org/stable/modules/generated/sklearn.cluster.KMeans.html