从元组列表创建唯一集合

时间:2019-01-05 22:41:40

标签: python set

我正在尝试创建相距50英里之内的独特大学集群。

我有一本字典,其中有一个元组,其中大学的名称为键,它们之间的距离为值:

{('University A', 'University B'): 2546,
 ('University A', 'University C'): 2449,
 ('University A', 'University D'): 5,
 ('University A', 'University E'): 1005,
 ('University B', 'University C'): 32,
 ('University B', 'University D'): 132,
 ('University B', 'University E'): 42,
 ('University C', 'University D'): 532,
 ('University C', 'University E'): 1362}

我能够过滤它们以获取彼此相距50英里之内的两所大学:

('University A', 'University D')
('University B', 'University C')
('University B', 'University E')

我如何遍历这些对并创建集群集?我最后应该得到的是大学A和D的一套,以及大学B,C和E的另一套。

实际上,我在看100所大学,因此,结对的数目要长得多。每当有新的大学集群时,我都在努力在迭代中创建新集。

2 个答案:

答案 0 :(得分:0)

答案不完整,但希望它能显示出需要测试和优化的想法。

将键作为一个集合过滤,然后遍历并使用联合(如果该对中的任何一对在查询列表中),该列表必须在迭代时进行更新。最好显示一些代码:

filtered = ([ set(k) for k,v in u.items() if v <= 50 ])
print(filtered) #=> [{'University A', 'University D'}, {'University B', 'University C'}, {'University B', 'University E'}]

lookup_list = filtered[1]
for pair in filtered:
  if any(e in lookup_list for e in pair):
    lookup_list = lookup_list.union(pair)

print(lookup_list)
#=> {'University B', 'University C', 'University E'}

答案 1 :(得分:0)

在@Daniel Mesejo和@Jon Clements以及this post的帮助下,我最终使用networkx解决了这个问题。

从元组clusters的列表开始,看起来像[('University A', 'University B'), ('University A', 'University C'), ...],我用以下方法创建了图形:

g = nx.Graph()
for c in clusters :
    g.add_edge(*c)
nx.draw(g)
plt.show()

Cluster graph

然后提取群集,并使用字典中的键值对为每个群集分配唯一的标识符,其中键是群集的编号,而值是该群集中节点(学校名称)的列表:

sub_graphs = list(nx.connected_component_subgraphs(g))
n = len(sub_graphs)
clusters = {}
for i in range(n) :
    clusters[i+1] = list(sub_graphs[i].nodes())

最后将它们映射回原始数据框:

def map_cluster(x) :
    for k, v in clusters.items() :
        if x in v :
            return k

df['Cluster'] = df['School Name'].apply(lambda x: map_cluster(x))

我敢肯定有一种更有效的方法可以做到这一点,并欢迎对此方法发表评论!

相关问题