我有如下图表:
P=nx.Graph()
P.add_node('node1',at=5)
P.add_node('node2',at=5)
P.add_node('node3',at=6)
我想访问at = 5的所有节点,而不必遍历所有节点(因此没有列表理解或为)。 IE,我想要一个关于属性值的倒排索引。
我可以添加一个字典,并在每次创建一个新节点时填写它(目前我是如何解决这个问题的)但是我想知道是否有较少的手工和容易出错(并且效率更高) )这样做的方式
at_dict = collections.defaultdict(set)
at_dict[5].add('node1')
at_dict[5].add('node2')
at_dict[6].add('node3')
请注意,我需要使用图形,因为我必须在节点上进行一些聚类(所以我不能完全改变我的数据结构)
答案 0 :(得分:1)
作为一种可能性,您可以通过以下方式继承nx.Graph
:
class MyGraph(nx.Graph):
def __init__(self, data=None, **attr):
super().__init__(data, **attr)
self.at_dict = collections.defaultdict(set)
def add_node(self, n, attr_dict=None, **attr):
super().add_node(n, attr_dict=attr_dict, **attr)
self.at_dict[attr.get("at")].add(n)
然后你可以这样使用它:
P=MyGraph()
P.add_node('node1', at=5)
P.add_node('node2', at=5)
P.add_node('node3', at=6)
P.at_dict[5]
>>>{'node1', 'node2'}
P.S:当然你必须覆盖其他方法,例如remove_node
,这样你的词汇就会保持连贯。要使用正确的参数覆盖,请参阅此链接,了解nx.Graph
类的来源:https://networkx.github.io/documentation/networkx-1.10/_modules/networkx/classes/graph.html
答案 1 :(得分:0)
图表是dict
中dict
的{{1}}。您可以定义以下功能:
networkx
[OUT]:
def get_nodes_by_attribute(G, att):
return [k for k,v in G.nodes(data=True) if list(v.values())[0] == att]
get_nodes_by_attribute(P, 5)
['node1', 'node2']
get_node_attributes()
[OUT]:
[k[0] for k in nx.get_node_attributes(P, 'at').items() if k[1] == 5]
但是,从source代码来看,它仍然是['node1', 'node2']
理解。
将dict
转换为元组列表:
dict
创建反向tpl = [(k,v) for k,v in nx.get_node_attributes(P, 'at').items()]
# reverse the tuples
l = [x[::-1] for x in tpl]
:
dict
[OUT]:
d = {}
for elem in l:
key = elem[0]
if key in d:
val = d[key]
val.append(elem[1])
d[key] = val
else:
d[key] = [elem[1]]
d