我正在尝试创建相距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所大学,因此,结对的数目要长得多。每当有新的大学集群时,我都在努力在迭代中创建新集。
答案 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()
然后提取群集,并使用字典中的键值对为每个群集分配唯一的标识符,其中键是群集的编号,而值是该群集中节点(学校名称)的列表:
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))
我敢肯定有一种更有效的方法可以做到这一点,并欢迎对此方法发表评论!