如何在不指定集群数量的情况下对列表中的项目进行集群

Posted

技术标签:

【中文标题】如何在不指定集群数量的情况下对列表中的项目进行集群【英文标题】:How to cluster items in a list without specifying the number of clusters 【发布时间】:2014-04-21 12:21:53 【问题描述】:

我的目标是根据任意两个连续项目之间的距离对下面列表中的项目进行聚类。未指定簇数,仅指定最大距离 在任何两个连续项目之间,不能超过它们才能在同一个集群中。

我的尝试

import itertools
max_dist=20
_list=[1,48,52,59,89,94,103,147,151,165]
Ideal_result= [[1],[48,52,59],[89,94,103],[147,151,165]]

def clust(list_x, max_dist):
    q=[]
    for a, b in itertools.combinations(list_x,2):
        if b-a<=20:
            q.append(a),(b)
        else:continue
        yield q
print list(clust(_list,max_dist))

输出:

[[48,48,52,89,89,94,147,147,151],[48,48,52,89,89,94,147,147,151],..]`

输出完全错误,但我只是想包含我的尝试。

关于如何获得理想结果的任何建议?谢谢。

【问题讨论】:

所有集群的大小都必须相同吗? @Two-BitAlchemist,不一定大小相同。重要的是任何两个连续项目之间的距离;从列表中的第一项开始(升序)。有关详细信息,请参阅理想结果。 NumPy 有一些层次聚类例程:docs.scipy.org/doc/scipy/reference/cluster.hierarchy.html,但这可能有点矫枉过正。 @JoshCaswell,感谢您的建议。我马上去查。 1D Number Array Clustering的可能重复 【参考方案1】:

这通过了你的测试:

def cluster(items, key_func):
    items = sorted(items)
    clusters = [[items[0]]]
    for item in items[1:]:
        cluster = clusters[-1]
        last_item = cluster[-1]
        if key_func(item, last_item):
            cluster.append(item)
        else:
            clusters.append([item])
    return clusters

如果当前项和以前的项应属于同一集群,则 key_func 返回 True

>>> cluster([1,48,52,59,89,94,103,147,151,165], lambda curr, prev: curr-prev < 20)
[[1], [48, 52, 59], [89, 94, 103], [147, 151, 165]]

另一种可能性是修改"equivalent code" for itertools.groupby() 以同样为键函数采用多个参数。

【讨论】:

以上是关于如何在不指定集群数量的情况下对列表中的项目进行集群的主要内容,如果未能解决你的问题,请参考以下文章

如何在不知道项目泛型类型参数的情况下对作为泛型给出的列表进行浅表复制? [复制]

如何在限制点之间的最大距离和每个集群的最大点数的情况下对 lat/lng 数据进行聚类

pd.dataframe - 在不更改索引的情况下对列表列中的每个列表进行排序

如何在不单独指定所有列的情况下对所有列的 SQL 结果进行排序?

在不知道它们的值的情况下对 Python 数字列表进行排序,而只知道它们之间的关系

如何在不消除坐标的情况下对浮点坐标进行排序? [关闭]