首页 > 解决方案 > 通过 NetworkX 中的属性检索节点时遇到问题

问题描述

我正在使用 NetworkX 开发一个代码,其中我有一个类似于以下的 Multipartite 图:

在此处输入图像描述

每个节点具有以下属性:

在上面的照片中,每个节点标签都被描述为“label.layer”(在这种情况下,我们可以看到更大图的一个子集,因此层号从 451 开始,而不是从 0 开始)。

我想从这个图中得到单独的字典,这些字典应该只包含属于同一轨迹的节点,即所有彼此相邻的节点。到目前为止,我关注了这些帖子,我的解决方案是:

选择具有给定属性值的网络节点

选择节点和边形成具有属性的networkx图

for i in range(trajectory):
        sel_nodes = dict((node, attribute['trajectory']) for node, attribute in G.nodes().items() if attribute['trajectory'] == i)
        print(sel_nodes)

这应该为每个“行”节点返回一个字典,但是输出是以下字典:

{'0.451': 0, '0.452': 0, '0.453': 0, '0.454': 0, '0.455': 0, '0.456': 0, '0.457': 0, '0.458': 0, '0.459': 0, '0.460': 0}
{'1.451': 1, '1.452': 1, '1.453': 1, '1.454': 1, '1.455': 1, '1.456': 1, '1.457': 1, '1.458': 1, '1.459': 1, '1.460': 1}
{'2.451': 2, '3.452': 2, '3.453': 2, '3.454': 2, '3.455': 2, '3.456': 2, '3.457': 2, '3.458': 2, '3.459': 2, '4.460': 2}
{'3.451': 3, '2.452': 3, '2.453': 3, '2.454': 3, '2.455': 3, '2.456': 3, '2.457': 3, '2.458': 3, '2.459': 3, '3.460': 3}
{'4.451': 4, '4.452': 4, '4.453': 4, '4.454': 4, '4.455': 4, '4.456': 4, '4.457': 4, '4.458': 4, '4.459': 4, '5.460': 4}
{'5.451': 5, '5.452': 5, '5.453': 5, '5.454': 5, '5.455': 5, '5.456': 5, '5.457': 5, '5.458': 5, '5.459': 5, '6.460': 5}
{'6.451': 6, '6.452': 6, '6.453': 6, '6.454': 6, '6.455': 6, '6.456': 6, '6.457': 6, '6.458': 6, '6.459': 6, '7.460': 6}
{'7.451': 7, '7.452': 7, '7.453': 7, '7.454': 7, '7.455': 7, '7.456': 7, '7.457': 7, '7.458': 7, '7.459': 7, '8.460': 7}
{'8.451': 8, '8.452': 8, '8.453': 8, '8.454': 8, '8.455': 8, '8.456': 8, '8.457': 8, '8.458': 8, '8.459': 8, '9.460': 8}
{}
{}

最后两个空字典应该分别包含下一行节点和图表最后一列的孤独节点,但事实并非如此,我只能检索以某种方式连接到第一个节点的节点柱子。

有没有办法解决这种行为?

编辑:为了缩小问题的范围,我相信问题在于我使用的字典理解,因为我已经检查了属性轨迹是否具有分配给它的值:

print(G.nodes['9.455']['trajectory']) 

输出给了我轨迹 9,它与我期望的轨迹一致。

标签: pythondictionarynetworkxgraph-theorydictionary-comprehension

解决方案


我觉得这里的字典列表是错误的数据结构。看起来你真的在寻找一个数据结构,它告诉你,给定一个轨迹i,哪些节点属于这个轨迹?集合或集合列表的字典似乎更合适。

以下是如何在一个小示例图上构建这样一个列表,其中顶部轨迹是一个孤立节点,底部两个相互交叉:

>>> import networkx as nx
>>> G = nx.Graph()
>>> G.add_nodes_from([(0.3, {"trajectory": 0}), (1.1, {"trajectory": 1}), (2.2, {"trajectory": 1}), (2.3, {"trajectory": 1}), (2.1, {"trajectory": 2}), (1.2, {"trajectory": 2}), (1.3, {"trajectory": 2})])
>>> from collections import defaultdict
>>> d = defaultdict(set)
>>> for node, attrs in G.nodes().items():
...     d[attrs["trajectory"]].add(node)
... 
>>> d
defaultdict(<class 'set'>, {0: {0.3}, 1: {1.1, 2.2, 2.3}, 2: {1.2, 2.1, 1.3}})

如果你真的想要上面描述的字典列表,你可以很容易地从这里构造它:

>>> for trajectory, nodes in d.items():
...     print({node: trajectory for node in nodes})
... 
{0.3: 0}
{1.1: 1, 2.2: 1, 2.3: 1}
{1.2: 2, 2.1: 2, 1.3: 2}

如果您想要每个轨迹的有序列表而不是一组,您可以对小数点后的名称部分进行排序:

>>> d = {k: sorted(nodes, key=lambda x: str(x)[2:]) for k, nodes in d.items()}
>>> d
{0: [0.3], 1: [1.1, 2.2, 2.3], 2: [2.1, 1.2, 1.3]}

推荐阅读