从过滤边的 subgraph_view 中获取 networkx 过滤节点
Get networkx filtered nodes from subgraph_view of filtered edges
我通过对边缘应用滤镜创建了一个 subgraph_view。当我在子图上调用 nodes()
时,它仍然显示所有节点,即使 none 的边使用它们。我需要获取仍然是子图一部分的节点的列表。
G = nx.path_graph(6)
G[2][3]["cross_me"] = False
G[3][4]["cross_me"] = False
def filter_edge(n1, n2):
return G[n1][n2].get("cross_me", True)
view = nx.subgraph_view(G, filter_edge=filter_edge)
# node 3 is no longer used by any edges in the subgraph
view.edges()
这会产生
EdgeView([(0, 1), (1, 2), (4, 5)])
符合预期。但是,当我 运行 view.nodes()
我得到
NodeView((0, 1, 2, 3, 4, 5))
我希望看到的是
NodeView((0, 1, 2, 4, 5))
这看起来很奇怪。有没有办法只提取子图使用的节点?[=17=]
混淆源于 'graph.' 断开连接的节点仍然是图的一部分的定义。事实上,你可以有一个 graph with no edges at all。所以 subgraph_view()
的行为违反直觉但却是正确的。
但是,如果您仍想实现所描述的内容,则有很多可能的方法,具体取决于您对修改原始图形的容忍度。我会提到两个尝试尽可能接近您当前的方法并避免 deleting edges or nodes 来自 G
.
方法一
使用 view
对象的最简单方法是将其作为 edge_subgraph()
的输入(仅将边作为输入),如下所示:
final_view = view.edge_subgraph(view.edges())
final_view.nodes()
给予
NodeView((0, 1, 2, 4, 5))
方法二
对我来说,方法 1 似乎笨拙且令人困惑,因为它定义了一个中间视图。相反,如果我们返回一点并从 G
开始,我们可以定义一个 filter_node
函数来检查每个节点的边属性并在
时过滤该节点
- 所有边都被标记为要删除,或者
- 节点首先没有边。
您也可以通过手动标记节点本身来完成此操作,就像您对边所做的那样。
G = nx.path_graph(6)
G[2][3]["cross_me"] = False
G[3][4]["cross_me"] = False
def filter_edge(n1, n2):
return G[n1][n2].get("cross_me", True)
def filter_node(n):
return sum([i[2].get("cross_me", True) for i in G.edges(n, data=True)])
view = nx.subgraph_view(G, filter_node=filter_node, filter_edge=filter_edge)
view.nodes()
也给出预期
NodeView((0, 1, 2, 4, 5))
我通过对边缘应用滤镜创建了一个 subgraph_view。当我在子图上调用 nodes()
时,它仍然显示所有节点,即使 none 的边使用它们。我需要获取仍然是子图一部分的节点的列表。
G = nx.path_graph(6)
G[2][3]["cross_me"] = False
G[3][4]["cross_me"] = False
def filter_edge(n1, n2):
return G[n1][n2].get("cross_me", True)
view = nx.subgraph_view(G, filter_edge=filter_edge)
# node 3 is no longer used by any edges in the subgraph
view.edges()
这会产生
EdgeView([(0, 1), (1, 2), (4, 5)])
符合预期。但是,当我 运行 view.nodes()
我得到
NodeView((0, 1, 2, 3, 4, 5))
我希望看到的是
NodeView((0, 1, 2, 4, 5))
这看起来很奇怪。有没有办法只提取子图使用的节点?[=17=]
混淆源于 'graph.' 断开连接的节点仍然是图的一部分的定义。事实上,你可以有一个 graph with no edges at all。所以 subgraph_view()
的行为违反直觉但却是正确的。
但是,如果您仍想实现所描述的内容,则有很多可能的方法,具体取决于您对修改原始图形的容忍度。我会提到两个尝试尽可能接近您当前的方法并避免 deleting edges or nodes 来自 G
.
方法一
使用 view
对象的最简单方法是将其作为 edge_subgraph()
的输入(仅将边作为输入),如下所示:
final_view = view.edge_subgraph(view.edges())
final_view.nodes()
给予
NodeView((0, 1, 2, 4, 5))
方法二
对我来说,方法 1 似乎笨拙且令人困惑,因为它定义了一个中间视图。相反,如果我们返回一点并从 G
开始,我们可以定义一个 filter_node
函数来检查每个节点的边属性并在
- 所有边都被标记为要删除,或者
- 节点首先没有边。
您也可以通过手动标记节点本身来完成此操作,就像您对边所做的那样。
G = nx.path_graph(6)
G[2][3]["cross_me"] = False
G[3][4]["cross_me"] = False
def filter_edge(n1, n2):
return G[n1][n2].get("cross_me", True)
def filter_node(n):
return sum([i[2].get("cross_me", True) for i in G.edges(n, data=True)])
view = nx.subgraph_view(G, filter_node=filter_node, filter_edge=filter_edge)
view.nodes()
也给出预期
NodeView((0, 1, 2, 4, 5))