【问题标题】:how to keep specific node in networkx如何在networkx中保留特定节点
【发布时间】:2021-03-13 06:56:08
【问题描述】:

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

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文件时,我得到了一些没有egdes的节点

5.我发现原因是我删除了与'pu.edu.tw'相关的链接,所以缺少一些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”,但只连接到不是来自该网站的节点,您想创建替代这种间接连接的边吗?说,有节点'A.pu.edu.tw'--B.oth--C.oth--D.pu.edu.tw,那么你要添加边A--C吗?
  • 是的!这就是我现在要做的。
  • 是的,如果您希望节点具有任何这些 ID,这就是这样做的方法

标签: python networkx spyder gml


【解决方案1】:

如果您只想维护来自每个孤立节点的一个连接,即与子图中“最近”节点的连接,您可以执行以下操作:创建子图后,遍历孤立节点并为每个节点执行 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 方法 -它更干净,适用于任意数量的已删除节点(与您可能知道的循环相反)。这样就创建了一个新的图形对象,而不是从旧图形对象中删除边——这对于上面介绍的算法是必要的。

【讨论】:

  • 名称'neigh' 未定义
  • 另外G.subgraph(desired_nodes) 会返回一条消息,指出您无法更改冻结的图形,这可能是因为他们不希望您冒险搞砸原始图形的一部分。相反,它应该是nx.Graph(G.subgraph(desired_nodes))。 Np ;)
【解决方案2】:

您可以做的一件事是保留其邻居名称中包含 "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)

【讨论】:

  • 如果有'pw.edu.tw'的节点通过超过2个没有这个标签的节点连接,它不会错过吗?
  • 是的。它只是在图中保留其邻居名称中包含“pu.edu.tw”的每个节点。
  • @willcrack 很抱歉,但仍有一些节点与其他节点隔离。
  • 你能找出原因吗?
  • 你检查过那些孤立的节点是否在原始图中没有被孤立吗?
【解决方案3】:

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

g_aux = g.to_undirected() 

为什么我必须使用g_aux 来运行这个程序?我不明白 NetworkX 中图形辅助的真正作用。

【讨论】:

  • g_aux 只是一个变量,它是图g的无向版本
  • 另外,您最好对您的问题进行编辑,而不是在回答帖子中提出问题。
  • 好的,我在原始帖子中更新了一个新问题,请检查一下......
  • 对不起,我找不到,能把链接发在这里吗?
  • 看看我原来的问题,我在下面添加了一个更新
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-04-27
  • 1970-01-01
  • 2012-11-28
  • 2018-05-08
  • 1970-01-01
  • 2021-01-06
相关资源
最近更新 更多