Networkx:节点属性的反向索引

时间:2018-04-13 09:01:37

标签: python networkx

我有如下图表:

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')

请注意,我需要使用图形,因为我必须在节点上进行一些聚类(所以我不能完全改变我的数据结构)

2 个答案:

答案 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)

按属性值

获取节点

图表是dictdict的{​​{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)

备选方案1:使用来自networkx的['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'] 理解。

备选方案2:创建反向索引

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