在网络图中获取直接边连接
Getting direct edge connections in a network graph
我有下面的网络图:
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)
我想构建一个给定网络、节点名称和关系类型的函数,return是与给定人员直接相关的人员列表。
这是我目前得到的函数:
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']
虽然这不是我所需要的,但我希望 return 仅那些与 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))
然而,这仍然是 return 错误的结果。
首先,重构您的函数定义,以便更容易理解:
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_net
(可能是整个事物)的完全连接的组件子图(称之为 relation_sub_net
)。
- 输出
relation_sub_net
的节点列表。这是您想要的输出。
如果您想尝试这样做,我相信如果您遇到困难,任何人(包括我自己)都会很乐意为您提供帮助。
根据 PMende
的指导,您的编码尝试非常 接近。问题出在您的第二次提取中,当您尝试仅提取与 John 相连的那些边时:
relation_subnet = nx.Graph([(node,v,d) for (u, v, d) in relation_net.edges( data = True)
if d["relation"] == relationship])
(u,v,d)的选择(node,v,d)错误,条件错误。在第一个子句中
(node,v,d) for (u, v, d) in ...
对于 relation_net
中的每个节点,您获取 src、dst 和 arc 值...但随后丢弃 src 并强制 John
进入该位置。这仅在 John
已经恰好是来源时才有效;否则,您刚刚创建了一个新的子网边缘,例如
("John","Jack", {"relation":"family"}) # Lakshmi removed
相反,您需要保留那些包含 John 的边缘 任一 位置。
其次,您的 "relation" 过滤器第二次什么都不做;你已经第一次包括了每一个家庭关系。相反,您需要收集出现在家庭边缘的所有与 John 在一起的人。
relation_subnet = nx.Graph([(u,v,d) for (u, v, d) in relation_net.edges( data = True)
if u == node or v == node])
这正确地产生了
['Samantha', 'Jill', 'John']
萨曼莎和吉尔是约翰唯一的直系 link 家庭。如果你想要这个列表上的串联闭包,那么你需要迭代这个过程,将每个新的 family
添加到 Jill and/or Samantha,重复直到没有添加新节点。
你能从那里拿走吗?
大家好 :) 我要感谢大家的时间和帮助,你们确实帮助我提高了我对我所面临的问题的认识和理解,现在我对网络有了更多的了解。我终于得到了我正在寻找的解决方案。事情是这样的:
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
我有下面的网络图:
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)
我想构建一个给定网络、节点名称和关系类型的函数,return是与给定人员直接相关的人员列表。
这是我目前得到的函数:
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']
虽然这不是我所需要的,但我希望 return 仅那些与 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))
然而,这仍然是 return 错误的结果。
首先,重构您的函数定义,以便更容易理解:
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_net
(可能是整个事物)的完全连接的组件子图(称之为relation_sub_net
)。 - 输出
relation_sub_net
的节点列表。这是您想要的输出。
如果您想尝试这样做,我相信如果您遇到困难,任何人(包括我自己)都会很乐意为您提供帮助。
根据 PMende
的指导,您的编码尝试非常 接近。问题出在您的第二次提取中,当您尝试仅提取与 John 相连的那些边时:
relation_subnet = nx.Graph([(node,v,d) for (u, v, d) in relation_net.edges( data = True)
if d["relation"] == relationship])
(u,v,d)的选择(node,v,d)错误,条件错误。在第一个子句中
(node,v,d) for (u, v, d) in ...
对于 relation_net
中的每个节点,您获取 src、dst 和 arc 值...但随后丢弃 src 并强制 John
进入该位置。这仅在 John
已经恰好是来源时才有效;否则,您刚刚创建了一个新的子网边缘,例如
("John","Jack", {"relation":"family"}) # Lakshmi removed
相反,您需要保留那些包含 John 的边缘 任一 位置。
其次,您的 "relation" 过滤器第二次什么都不做;你已经第一次包括了每一个家庭关系。相反,您需要收集出现在家庭边缘的所有与 John 在一起的人。
relation_subnet = nx.Graph([(u,v,d) for (u, v, d) in relation_net.edges( data = True)
if u == node or v == node])
这正确地产生了
['Samantha', 'Jill', 'John']
萨曼莎和吉尔是约翰唯一的直系 link 家庭。如果你想要这个列表上的串联闭包,那么你需要迭代这个过程,将每个新的 family
添加到 Jill and/or Samantha,重复直到没有添加新节点。
你能从那里拿走吗?
大家好 :) 我要感谢大家的时间和帮助,你们确实帮助我提高了我对我所面临的问题的认识和理解,现在我对网络有了更多的了解。我终于得到了我正在寻找的解决方案。事情是这样的:
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