[英]Python clustering list of sets
对于一组集合,我需要将它们分组到多个“集群”中,集群中的所有节点都是该集群中最大节点的子集。 例如
input = [{1, 2}, {1, 2, 3}, {1, 2, 4}, {1, 4}, {1}]
将得到:
[{1, 2, 3}, {1, 2}, {1}],
[{1, 2, 4}, {1, 2}, {1, 4}, {1}]
我已经尝试参考this构建一个子集树,但是当输入很大时它很快就会变得非常慢,因为它会为每次插入迭代所有子节点。
我不熟悉 k-mean 聚类,但它是否适用于这里的问题?
最有效的方法是什么?
首先按长度降序对列表进行排序。 这样你就从最长的集合开始,这些集合肯定不是任何其他集合的子集。
然后,将每个代表集保存为具有列表值的字典的键(转换为元组后)。
对于每个集合,检查它是否是任何键的子集并将其添加到相应的列表中。
只有当它没有被添加到任何键时,它才意味着它是一个新的代表。
最后,取结果字典的values()
:
l = [{1, 2}, {1, 2, 3}, {1, 2, 4}, {1, 4}, {1}]
grouped_sets = {}
for cur_set in sorted(l, key=len, reverse=True):
is_subset = False
for represent, sets in grouped_sets.items():
if cur_set.issubset(represent):
sets.append(cur_set)
is_subset = True
if not is_subset:
grouped_sets[tuple(cur_set)] = [cur_set]
print(list(grouped_sets.values()))
这使:
[[{1, 2, 3}, {1, 2}, {1}],
[{1, 2, 4}, {1, 2}, {1, 4}, {1}]]
也许按长度递减的顺序对集合进行排序会将交叉点的数量减少到每个集群每个集合一个。 这将取决于数据,如果没有子集,则不会改善,但随着集群更大,它应该会改善:
setList = [{1, 2}, {1, 2, 3}, {1, 2, 4}, {1, 4}, {1}]
groups = []
for aSet in sorted(setList,key=len,reverse=True):
clusters = [g for g in groups if g[0].issuperset(aSet)]
if not clusters:
groups.append([])
clusters = groups[-1:]
for g in clusters:
g.append(aSet)
print(groups)
[[{1, 2, 3}, {1, 2}, {1}], [{1, 2, 4}, {1, 2}, {1, 4}, {1}]]
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.