как сохранить определенный узел в networkx

#python #networkx #spyder #gml

#python #networkx #spyder #gml

Вопрос:

В настоящее время я изучаю специальную тему в колледже. Моя проблема в том, что я могу удалить весь узел, который мне не нужен, но я хочу сохранить какой-то конкретный узел. Вот как я это делаю.

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.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. Проблема в том, что когда я пытаюсь нарисовать этот файл gml с помощью networkx, у меня есть несколько узлов без egde
введите описание изображения здесь

5. И я выяснил, что причина в том, что я удалил ссылку, связанную с ‘pu.edu.tw » значит, не хватает нескольких эгдэ

Я хочу знать, как не только удалить ненужный мне веб-сайт, но и сохранить конкретный узел, связанный с ‘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)
 

это правильный способ сделать?

Комментарии:

1. Итак, эти сироты принадлежат ‘pu.edu.tw ‘, но были подключены только к узлам, которые не с этого веб-сайта, и вы хотите создать ребра, которые заменяют такие косвенные соединения? Скажем, там были узлы ‘A.pu.edu.tw ‘ … Б.от … К.от … D.pu.edu.tw , тогда вы хотите добавить ребро A — C?

2. Да! это то, что я пытаюсь сделать прямо сейчас.

3. Да, это способ сделать это, если вы хотите, чтобы узлы имели любой из этих идентификаторов

Ответ №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")
 

Я также изменил метод удаления узлов из графика — вместо реализованного вами двойного цикла я сначала нахожу узлы с нужным свойством с помощью сопоставления списка, а затем использую subgraph метод from networkx.Graph — он более чистый и будет работать для произвольного количества удаленных узлов (в отличие от циклов, которые вывероятно, знают). Таким образом создается новый объект graph вместо удаления ребер из старого, что необходимо для алгоритма, представленного выше.

Комментарии:

1. имя 'neigh' не определено

2. Также 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() , сохраняя каждого соседа a "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)
 

Комментарии:

1. Разве это не пропустит случаи, когда узлы с 'pw.edu.tw' подключены через более чем 2 узла без этой метки?

2. Да, это было бы. Он просто сохраняет на графике каждый узел, у соседа которого есть «pu.edu.tw «во имя этого.

3. @willcrack извините, но все еще есть несколько узлов, которые изолированы от других.

4. Вы смогли определить, почему?

5. Вы проверили, не были ли эти изолированные узлы изолированы в исходном графике?

Ответ №3:

Вот вопрос, который я хочу задать….

 g_aux = g.to_undirected() 
 

почему я должен использовать g_aux для запуска этой программы? я не понимаю, что на самом деле делают вспомогательные графы в NetworkX.

Комментарии:

1. g_aux это просто переменная, это неориентированная версия графика g

2. Кроме того, было бы предпочтительнее, чтобы вы добавили редактирование к своему вопросу, чем задавать вопрос в сообщении ответа.

3. хорошо, я обновил новый вопрос в моем первоначальном посте, пожалуйста, проверьте это….

4. Извините, я не могу его найти, вы можете разместить ссылку здесь?

5. просто проверьте мой первоначальный вопрос, я добавил обновление ниже