我有以下网络图:
import networkx as nx
net = nx.Graph()
node_list = ["Gur","Qing","Samantha","Jorge","Lakshmi","Jack","John","Jill"]
edge_list = [("Gur","Qing",{"relation":"work"}),
("Gur","Jorge", {"relation":"family"}),
("Samantha","Qing", {"relation":"family"}),
("Jack","Qing", {"relation":"work"}),
("Jorge","Lakshmi", {"relation":"work"}),
("Jorge","Samantha",{"relation":"family"}),
("Samantha","John", {"relation":"family"}),
("Lakshmi","Jack", {"relation":"family"}),
("Jack","Jill", {"relation":"charity"}),
("Jill","John",{"relation":"family"})]
net.add_nodes_from(node_list)
net.add_edges_from(edge_list)
我想构建一个给定网络,节点名称和关系类型的函数,该函数返回给定人员直接连接的人员列表。
这是我到目前为止获得的功能:
def get_relations(graph,node,relationship):
if relationship == 'charity':
charity = [ (v) for (u,v,d) in net.edges( data = True) if d["relation"]=="charity"]
return list(set(charity))
else:
if relationship == 'work':
work = [ (v) for (u,v,d) in net.edges( data = True) if d["relation"]=="work"]
return list(set(work))
else:
if relationship == 'family':
family = [(v) for (u,v,d) in net.edges( data = True) if d["relation"]=="family"]
return list(set(family))
else:
return None
这样调用函数:
get_connections(net, 'John', 'family')
产生以下输出:
['Gur', 'Samantha', 'John', 'Lakshmi']
这不是我所需要的,我希望它仅返回那些直接连接到John的人,或者返回具有直接路径而不是间接路径的任何节点。
以相同的方式调用该函数应将其产生为正确的输出:
['John', 'Jill', 'Samantha', 'Qing', 'Jorge', 'Gur']
尝试输入代码:
def get_relations(graph,node,relationship):
if relationship not in {'charity', 'work', 'family'}:
return None
relation_net = nx.Graph([(u,v,d) for (u, v, d) in net.edges( data = True)
if d["relation"] == relationship])
relation_subnet = nx.Graph([(node,v,d) for (u, v, d) in relation_net.edges( data = True)
if d["relation"] == relationship])
return list(set(relation_subnet.nodes))
但是,这仍然返回错误的结果。
答案 0 :(得分:3)
首先,重构您的函数定义,以便更容易理解:
def get_relations(graph,node,relationship):
if relationship not in {'charity', 'work', 'family'}:
return None
connections = [v for (u, v, d) in G.edges(data = True) if d["relation"] == relationship]
return list(set(connections))
然后使用较小的网络对其进行测试(也使事情更容易发生):
node_list = ["Gur","Qing","Samantha","Jorge","Lakshmi","Jack","John","Jill"]
edge_list = [
("Jack","Qing", {"relation":"work"}),
("Gur","Jorge", {"relation":"family"}),
("Samantha","Qing", {"relation":"family"}),
("Jorge","Samantha",{"relation":"family"}),
("Lakshmi","Jack", {"relation":"family"}),
("Jill","John",{"relation":"family"})
]
net = nx.Graph()
net.add_nodes_from(node_list)
net.add_edges_from(edge_list)
我们可以立即看到您的函数无法满足您的需求:
对get_relations(G, 'John', 'family')
的调用产生以下输出:
['Jack', 'Jorge', 'Jill', 'Samantha']
您没有逻辑在代码中的任何地方使用所需的节点。
您真正应该做的是:
net
属性和由其连接的所有节点的'relation'
子图(称为relation_net
)relation_sub_net
(可能是整个事物)的完全连接的组件子图(称为relation_net
)。relation_sub_net
的节点列表。这是您想要的输出。如果您想尝试一下,我敢肯定,如果您遇到困难,很多人(包括我自己)都会很乐意为您提供帮助。
答案 1 :(得分:2)
根据Parent
的指南,您的编码尝试非常接近。问题出在您的第二次提取中,当您尝试仅获取那些连接到John的边时:
state
(u,v,d)的选择(node,v,d)错误,并且条件错误。在第一句
Child
对于PMende
中的每个节点,请获取src,dst和arc值...,然后丢弃src并将relation_subnet = nx.Graph([(node,v,d) for (u, v, d) in relation_net.edges( data = True)
if d["relation"] == relationship])
强制插入该位置。仅当(node,v,d) for (u, v, d) in ...
已经恰好是源时才有效;否则,您只是创建了一个新的子网边缘,例如
relation_net
相反,您需要将包括约翰在内的那些边缘保持在 位置。
第二,您的“关系”过滤器第二次不执行任何操作;您已经第一次包括了所有家庭关系。取而代之的是,您需要收集与约翰一起出现在家庭边缘的每个人。
John
这可以正确产生
John
Samantha和Jill是John的唯一直接联系家庭。如果要在此列表上进行串联关闭,则需要迭代该过程,将("John","Jack", {"relation":"family"}) # Lakshmi removed
的每个新用户添加到Jill和/或Samantha中,重复进行直到没有新节点添加。
你能从那里拿走吗?
答案 2 :(得分:2)
再次向大家问好:)我要感谢大家的宝贵时间和帮助,您的确帮助我提高了对所面临问题的了解和了解,现在我对网络有了更多的了解。我终于找到了我想要的解决方案。就是这样:
def get_relations(graph,node,relationship):
if relationship not in {'charity', 'work', 'family'}:
return None
relation_net = nx.Graph([(u,v,d) for (u,v,d) in net.edges(nbunch = net.nodes(), data = True) if u == node or v == node])
relation_subnet = nx.Graph([(u,v,d) for (u,v,d) in net.edges(nbunch = relation_net.nodes(), data = True) if d['relation']== relationship])
relation1 = nx.Graph([(u,v,d) for (u,v,d) in net.edges(nbunch = relation_subnet.nodes(), data = True) if d['relation'] == relationship])
relation2 = nx.Graph([(u,v,d) for (u,v,d) in net.edges(nbunch = relation1.nodes(), data = True) if d['relation'] == relationship])
return list(set(relation2))
我发布此信息是因为也许我认为这可能会在某个时候帮助某人。没有你们的帮助,我做不到。再次感谢:D