我正在尝试编写K-means聚类程序,它需要欧几里德距离。我理解当数据存储在列表中时它是如何工作的,如下面的代码。
for featureset in data:
distances = [np.linalg.norm(featureset - self.centroids[centroid]) for centroid in self.centroids]
cluster_label = distances.index(min(distances))
但是我的数据集非常大(大约400万行)所以使用列表或数组绝对不是很有效。我想将数据存储在dataframe中。我正在考虑迭代data
的每一行并进行欧几里德计算,但即使我使用iteruples()
或iterrows
,它似乎也不那么有效。我想知道是否有更有效的方法来做到这一点。
答案 0 :(得分:1)
当您计算列表推导中的距离时,centroid
已经是列表self.centroids
的元素,因此无需在规范计算中再次对其进行补充。您提供的代码可能应该更改为:
distances = [np.linalg.norm(featureset - centroid) for centroid in self.centroids]
但是,如果您使用np.array
进行data
存储,则可能效率更高:
cluster_label = np.linalg.norm(self.centroids - featureset, axis=1).argmin()
让我们定义将返回某些featureset
的质心标签的函数:
def get_label(featureset):
return np.linalg.norm(self.centroids - featureset, axis=1).argmin()
现在我们可以在整个数据集中应用此功能:
labels = np.apply_along_axis(get_label, 1, data)
如果data
太大而无法处理为单np.array
,您可能会将其拆分为较小的和平,分别处理它们,然后连接结果。