Python: Как мне разобрать и отредактировать атрибут для всех ребер из файла gxl в networkx - PullRequest
1 голос
/ 05 марта 2020

У меня есть файл GXL с узлами и граничными атрибутами следующим образом:

<?xml version="1.0"?>
<gxl>
  <graph id="Network" edgeids="true" edgemode="undirected">
    <node id="_103">
      <attr name="OTU"><int>103</int></attr>
      <attr name="Bacteria"><string>Bif</string></attr>
    </node>
    :
    :
    :

<edge from="_103" to="_147">
  <attr name="nlr"><float>0.106</float></attr>
</edge>
<edge from="_103" to="_152">
  <attr name="nlr"><float>0.343</float></attr>
</edge>
    :
    :
    :

Я поделился ссылкой Googledrive с рабочим примером: https://drive.google.com/file/d/1HO4B_yLyEOhhRMN6YlmsaHdn2vQ1s1Yw/view?usp=sharing Я проанализировал этот файл в netwrokx используя ElementTree следующим образом:

tree_gxl = ET.parse("CONTROL1.gxl")
root_gxl = tree_gxl.getroot()
node_id = []
edge_attr={}
# Parse nodes
for i, node in enumerate(root_gxl.iter('node')):
    node_id += [node.get('id')]

node_id = np.array(node_id)
# Create adjacency matrix
am = np.zeros((len(node_id), len(node_id)))
##Parsing edges
for edge in root_gxl.iter('edge'):
    s = np.where(node_id==edge.get('from'))[0][0]
    t = np.where(node_id==edge.get('to'))[0][0]
# Undirected Graph
    am[s,t] = 1
    am[t,s] = 1
# Create the networkx graph
G = nx.from_numpy_matrix(am)

Мне нужно выполнить следующие шаги: 1. Разобрать атрибуты ребер в графе G 2. После анализа мне нужно заменить значения в атрибутах ребер следующим образом:

(nlr*13.54)-13.54

nlr будет заменен каждым атрибутом ребра

Как я могу продолжить это?

1 Ответ

1 голос
/ 05 марта 2020

Я посмотрел на это и решил бы так:

import xml.etree.ElementTree as ET
import numpy as np 
import networkx as nx
import re

G=nx.Graph()

tree_gxl = ET.parse("CONTROL1.gxl")
root_gxl = tree_gxl.getroot()
node_id = []
edge_attr={}
# Parse nodes
for i, node in enumerate(root_gxl.iter('node')):
    node_id += [node.get('id')]

node_id = np.array(node_id)
# Create adjacency matrix
am = np.zeros((len(node_id), len(node_id)))
##Parsing edges
for edge in root_gxl.iter('edge'):
    s = np.where(node_id==edge.get('from'))[0][0]
    t = np.where(node_id==edge.get('to'))[0][0]

    # Get the child node of the current edge for the nrl value
    for node in edge:
      content = ET.tostring(node).decode("utf-8") 
      # Get the nrl value via regex
      r1 = re.findall(r"\d.\d+",content)       

      # Modify value according to: (nlr*13.54)-13.54       
      r1 = (float(r1[0])*13.54)-13.54

    #Add edge with original node names and nlr value to graph
    G.add_edge(node_id[s],node_id[t], nlr=r1)

Я не очень знаком с обработкой файлов xml, поэтому я не мог понять, как правильно получить значение с плавающей точкой. Вот почему я решил эту проблему немного сложнее, получив дочерний элемент ребра, а затем используя регулярное выражение для сопоставления со значением с плавающей точкой.

Я также заметил, что ваш результирующий граф не имеет исходных меток узлов, потому что вы сохраняя его в матрице и имя теряется там.

Так что я бы предложил использовать метод из графиков NetworkX вместо:

add_edge(nodex,nodey, attribute=value)

Вы можете сравнить вывод вашего кода и мой предложенный код с G.edges.data(), который вернет края с соответствующими атрибутами.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...