如何在networkx中保留特定节点

how to keep specific node in networkx

我目前正在研究我的大学专题。我的问题是我可以删除所有我不想要的节点,但我想保留一些特定的节点。这是我的做法。

1.read gml 到 networkx

2.using这段代码删除我不想要的网站,然后将其写入新的gml 文件

import networkx as nx
G = nx.read_gml('test.gml')
for i in range(2000):
    for node in G.nodes:
        if "pu.edu.tw" not in node:
            G.remove_node(node)
            break
nx.write_gml(G,"finaltest.gml")

3.As你可以看到这个gml文件的部分,我成功保留了所有'pu.edu.tw'网站

graph [
directed 1
multigraph 1
node [
  id 0
  label "https://www.pu.edu.tw/"
]
node [
  id 1
  label "https://alumni.pu.edu.tw/"
]
node [
  id 2
  label "https://freshman.pu.edu.tw/"
]
node [
  id 3
  label "https://tdc.pu.edu.tw/"
]
node [
  id 4
  label "https://alcat.pu.edu.tw/"
]
node [
  id 5
  label "https://www.secretary.pu.edu.tw/"
]
node [
  id 6
  label "https://pugive.pu.edu.tw/"
]

4.The 问题是当我尝试用 networkx 绘制这个 gml 文件时,我得到了一些没有 egdes 的节点

5.And 我发现原因是我删除了与 'pu.edu.tw' 相关的 link 所以缺少一些 egdes

我想知道如何不仅删除我不想要的网站并保留与 'pu.edu.tw' 相关的特定节点,这样边缘就不会丢失。或者以某种方式重新连接节点。谢谢。

-------------------------------------------- ----------------------------------

更新一个新问题.... 如果我想添加多个条件怎么办,比如

def cleanup(g):
    g_aux = g.to_undirected()
        for node in g_aux.nodes:
            if ("tku.edu.tw"or"scu.edu.tw"or"cycu.edu.tw"or"fcu.edu.tw") not in node:
            for neighbor in g_aux.neighbors(node):
                if "tku.edu.tw"or"scu.edu.tw"or"cycu.edu.tw"or"fcu.edu.tw" in neighbor:
                    break
            else:
                g.remove_node(node)

这是正确的做法吗?

您可以做的一件事是保留其邻居名称中包含 "pu.edu.tw" 的每个节点。

完整代码如下:

import networkx as nx

def cleanup(g):
    g_aux = g.to_undirected()
    for node in g_aux.nodes:
        if "pu.edu.tw" not in node:
            for neighbor in g_aux.neighbors(node):
                if "pu.edu.tw" in neighbor:
                    # Found
                    break
            else:
                # Didn't find pu.edu.tw in any neighbors
                g.remove_node(node)

G = nx.read_gml('test.gml')
cleanup(G)
nx.write_gml(G,"finaltest.gml")

得到的结果是每个节点"pu.edu.tw"及其邻居。
请注意,我使用了图的无向版本 g_aux = g.to_undirected(),使 "pu.edu.tw" 的每个邻居独立于连接边的方向。

这里有一些代码可以检查 pu.edu.tw 是否没有任何邻居:

def check_isolated(g):
    for node in g.nodes:
        if "pu.edu.tw" in node:
            if g.degree[node] == 0:
                print(node)

如果在 运行 cleanup 之前输出任何内容,那么这些节点将始终被隔离。

print(“before”)
check_isolated(g)
print(“cleaning...”)
cleanup(g)
print(“after”)
check_isolated(g)

如果您只想维护来自每个孤立节点的一个连接,即与您的子图中“最接近”节点的连接,您可以执行以下操作:创建子图后,遍历孤立节点并为每个孤立节点执行 BFS 算法 在原始图 上,当您找到具有标签 'pw.edu.tw' 的节点时停止并从该节点添加一条新边到孤儿节点 在子图中。使用 BFS,您可以保证找到具有所需 属性.

的最近节点

下面的代码应该可以解决问题:

import networkx as nx
from networkx.algorithms.traversal.breadth_first_search import bfs_edges

G = nx.read_gml('test.gml')

desired_nodes = [node for node in G.nodes if 'pu.edu.tw' in node]
subgraph = nx.Graph(G.subgraph(desired_nodes))

orphan_nodes = [node for node in subgraph.nodes if 
subgraph.degree[node] == 0]

for orphan in orphan_nodes:
    for _, neigh in bfs_edges(G, orphan):
        if 'pu.edu.tw' in neigh:
            subgraph.add_edge(neigh, orphan)
            break
            
nx.write_gml(subgraph,"finaltest.gml")

我还更改了从图中删除节点的方法 - 我首先使用列表理解找到具有所需 属性 的节点,然后利用 subgraph 来自 networkx.Graph 的方法 - 它更简洁,适用于任意数量的已删除节点(与您可能知道的循环相反)。这样就创建了一个新的图形对象,而不是从旧图形对象中删除边——这对于上面介绍的算法是必需的。

这是我想问的问题....

g_aux = g.to_undirected() 

为什么我必须使用 g_aux 到 运行 这个程序?我不明白 graph auxiliary 在 NetworkX 中到底做了什么。