首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >从过滤边的subgraph_view中获取网络过滤节点

从过滤边的subgraph_view中获取网络过滤节点
EN

Stack Overflow用户
提问于 2021-06-05 04:37:37
回答 1查看 491关注 0票数 1

我通过将过滤器应用到边缘创建了一个subgraph_view。当我在子图上调用nodes()时,它仍然向我显示所有节点,即使没有一个边使用它们。我需要一个仅包含仍然是子图一部分的节点的列表。

代码语言:javascript
复制
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()

这会产生

代码语言:javascript
复制
EdgeView([(0, 1), (1, 2), (4, 5)])

如预期的那样。但是,当我运行view.nodes()时,

代码语言:javascript
复制
NodeView((0, 1, 2, 3, 4, 5))

我希望看到的是

代码语言:javascript
复制
NodeView((0, 1, 2, 4, 5))

这听起来很奇怪。有什么方法只提取子图所使用的节点吗?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2021-06-07 07:40:46

这种混淆源于“图形”的定义。断开连接的节点仍然是图的一部分。实际上,您可以拥有一个完全没有边的图。因此,subgraph_view()的行为是违反直觉的,但是是正确的。

但是,如果您仍然希望实现您所描述的目标,那么有很多潜在的方法,这取决于您对修改原始图的容忍度。我将提到两个试图尽可能接近当前方法并避免删除边或节点来自G的方法。

方法1

使用view对象的最简单方法是将其作为edge_subgraph()的输入(只接受边缘作为输入),如下所示:

代码语言:javascript
复制
final_view = view.edge_subgraph(view.edges())
final_view.nodes()

给出

代码语言:javascript
复制
NodeView((0, 1, 2, 4, 5))

方法2

在我看来,通过定义中间视图,方法1显得笨拙和混乱。如果我们回过头来从G开始,我们可以定义一个filter_node函数来检查每个节点的边缘属性,如果

  1. 所有边缘都标记为移除,或
  2. 该节点首先没有边缘。

您也可以通过手动标记节点本身来做到这一点,就像对边缘所做的那样。

代码语言:javascript
复制
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()

也给出了预期的

代码语言:javascript
复制
NodeView((0, 1, 2, 4, 5))
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/67846314

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档