Networkx给出了错误的节点度数

Networkx giving the wrong degree of nodes

Networkx 似乎给出了错误的学位,它似乎给出了我期望的两倍。我通过以下方式对此进行了测试:

for i in G.nodes:
    print(i, G.degree(i), G.edges(i))

这给出了输出:

326171990 4 [(326171990, 915446299), (326171990, 911571535)]
911571527 2 [(911571527, 911571535)]
911571535 6 [(911571535, 326171990), (911571535, 911571527), (911571535, 6821895165)]
915446298 4 [(915446298, 915446299), (915446298, 915446302)]
915446299 4 [(915446299, 915446298), (915446299, 326171990)]

如您所见,它似乎提供了应有的双倍学位。这是针对具有许多节点的多重图,多重图是从使用 osmnx 库创建的 MultiDiGraph 转换而来的。我在进一步检查后发现的一个是,过去指向一个方向的边缘在节点的度数中得到了正确的解释。 Osmnx 将双向道路表示为每个方向上的两条边,这可能是原因,如果是这样,为什么边似乎没有被列出两次。对此问题的任何帮助将不胜感激。

这可能是因为您的图形是有向的。具有 4 条边的节点的度数为 4,但 G.edges(node) 只会 return 来自该节点的边,而不是指向它的边。

您可以使用 G.in_edges(node)

访问指向节点的边

有向图 H 与无向图 G 的示例:

df = pd.DataFrame({a:np.random.randint(0,10,10) for a in 'ab'})
df 

    a   b
0   3   1
1   5   8
2   0   3
3   4   0
4   3   7
5   9   3
6   3   2
7   4   9
8   6   1
9   2   4

G = nx.from_pandas_edgelist(df, source='a', target='b')
H = nx.from_pandas_edgelist(df, source='a', target='b', create_using =nx.DiGraph())
pos = nx.spring_layout(G)

plt.subplot(121)
nx.draw_networkx(G, pos=pos)
plt.subplot(122)
nx.draw_networkx(H, pos=pos)

for i in G.nodes:
    print(i, G.degree(i), G.edges(i))

3 5 [(3, 1), (3, 0), (3, 7), (3, 9), (3, 2)]
1 2 [(1, 3), (1, 6)]
5 1 [(5, 8)]
8 1 [(8, 5)]
0 2 [(0, 3), (0, 4)]
4 3 [(4, 0), (4, 9), (4, 2)]
7 1 [(7, 3)]
9 2 [(9, 3), (9, 4)]
2 2 [(2, 3), (2, 4)]
6 1 [(6, 1)]


for i in H.nodes:
    print(i, H.degree(i), H.edges(i), H.in_edges(i))

3 5 [(3, 1), (3, 7), (3, 2)] [(0, 3), (9, 3)]
1 2 [] [(3, 1), (6, 1)]
5 1 [(5, 8)] []
8 1 [] [(5, 8)]
0 2 [(0, 3)] [(4, 0)]
4 3 [(4, 0), (4, 9)] [(2, 4)]
7 1 [] [(3, 7)]
9 2 [(9, 3)] [(4, 9)]
2 2 [(2, 4)] [(3, 2)]
6 1 [(6, 1)] []

作为参考,这里的答案是使用OSMnx的get_undirected函数从MultiDiGraph转换为MultiGraph。这处理了从道路中心线边缘的有向图转换为无向图的怪癖,其中单个边缘代表单个物理路段,包括确保在它们的几何形状不同时保持平行边缘。无论何时您想使用 OSMnx 获得无向街道网络表示,此功能都是最佳选择。