如何在networkx中保留特定节点

2024-04-19 10:28:47 发布

您现在位置:Python中文网/ 问答频道 /正文

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

1.将gml读入networkx

2.使用此代码删除我不想要的网站,然后将其写入新的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.正如你看到的这个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.问题是当我试图用networkx绘制这个gml文件时,我得到了一些没有EGDE的节点 enter image description here

5.我发现原因是我删除了与“pu.edu.tw”相关的链接,因此缺少一些EGDE

我想知道如何不仅删除我不想要的网站,而且保留与“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)

这样做对吗


Tags: or文件inhttpsnetworkxidnodefor
3条回答

如果您只想从每个孤立节点维护一个连接,即从您的子图中具有“最近”节点的连接,则可以执行以下操作:创建子图后,迭代孤立节点,并对每个孤立节点在原始图上执行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")

我还更改了从图形中删除节点的方法-而不是您实现的双循环,我首先使用列表压缩查找具有所需属性的节点,然后利用networkx.Graph中的subgraph方法-它更干净,可以处理任意数量的删除节点(与您可能知道的循环相反)通过这种方式创建一个新的图形对象,而不是从旧图形对象中删除边,这是上述算法所必需的

我想问一个问题

g_aux = g.to_undirected() 

为什么我必须使用g_aux来运行这个程序?我不明白图形辅助工具在NetworkX中到底做了什么

您可以做的一件事是将其邻居具有"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)

相关问题 更多 >