NetworkX получает доступ к узлам с несколькими атрибутами - PullRequest
1 голос
/ 27 сентября 2019

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

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

Итак, для следующей сетиимпортировать networkx как nx

G = nx.Graph()
for i in range(0, 4):
    G.add_node(i)

attrs = {0:{'type':'A', 'name':'Amy'}, 1:{'type':'A', 'name':'Bob'}, 2:{'type':'B'}, 3:{'type':'B'}, 4:{'type':'C'}}
nx.set_node_attributes(G, values=attrs)

print([node for node,attr in G.nodes(data=True) if ((attr['type']=="A") & (attr['name']=='Amy'))][0])

Я ожидал, что он распечатает индекс узла для первого узла 0, но вместо этого я получаю KeyError: 'name'.

В большинстве случаевPython, логические условия обрабатываются слева направо, так что второе условие оценивается только в том случае, если первое условие оценивается как True (оно работает в Pandas), но здесь, похоже, это не так.

Например, это работает, если я сначала создаю подграф моего графа по типу:

H = G.subgraph([node for node,attr in G.nodes(data=True) if attr['type']=="A"])
print([node for node,attr in H.nodes(data=True) if attr['name']=='Amy'][0])

Поскольку все узлы типа A имеют свойство name, я больше не получаю ошибку при поиске по именина графике H, но NetworkX должен оценивать оба логических условия, когда я пытаюсь сделать это за один шаг на графике G.

Так что доступ к атрибутам типов и подтипов быстро становитсяогромная боль и лишняя память, если мне нужно создать подграф для каждого типа и подтипа узла в моем графике.

Есть ли лучший способ извлечь определенные узлы (или группы узлов) на основе атрибутов, которые тольконекоторые узлы в иерархическом порядке, чтобы избежать этой проблемы?Мне нравится использовать списки, но, очевидно, здесь это может не сработать, поэтому я, безусловно, открыт для других способов решения этой проблемы.

1 Ответ

1 голос
/ 27 сентября 2019

Для любого networkx атрибуты элемента графика хранятся в общем Python dict:

import networkx as nx

G = nx.Graph()
G.add_node(1, waka=1)
G.nodes(data=True)[1]

{'waka': 1}

Так что если вы не хотитечтобы вызвать KeyError исключений, вы можете использовать функцию dict.get() вместо доступа к элементу dict:

get(key[, default])

Возвращать значение для ключа, еслиключ находится в словаре, иначе по умолчанию.Если значение по умолчанию не задано, оно по умолчанию равно None, поэтому этот метод никогда не вызывает KeyError.


Вот пример:

Этот код:

import networkx as nx

G = nx.Graph()
G.add_node(1, waka=1)
G.add_node(2, waka=2)
G.add_node(3, attr='Q')
print([
    node
    for node, attr in G.nodes(data=True)
    if ((attr['waka'] != 1) & (attr['attr'] == 'Q'))
][0])

повысит KeyError:

KeyError: 'attr'

И этот код:

import networkx as nx

G = nx.Graph()
G.add_node(1, waka=1)
G.add_node(2, waka=2)
G.add_node(3, attr='Q')
print([
    node
    for node, attr in G.nodes(data=True)
    if ((attr.get('waka') != 1) & (attr.get('attr') == 'Q'))
][0])

будет работать:

3

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