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
。
因此,如果我必须为图中的每个节点类型和子类型制作一个子图,那么快速访问类型和子类型的属性将成为一个巨大的痛苦和记忆memory。
是否有更好的方法可以基于仅某些节点具有分层属性的属性来提取特定节点(或节点组),以避免此问题?我喜欢使用列表理解,但是显然它可能在这里不起作用,因此我当然愿意接受其他解决方法。
答案 0 :(得分:1)
对于任何networkx
图形元素,属性都存储在通用Python字典中:
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])
如果key在字典中,则返回key的值,否则返回默认值。如果未提供默认值,则默认值为
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