Networkx дает неправильную степень узлов - PullRequest
2 голосов
/ 17 июня 2020

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

Как вы можете видеть, это дает удвоенную степень, которой должно быть. Это для мультиграфа с множеством узлов, мультиграф был преобразован из MultiDiGraph, созданного с использованием библиотеки osmnx. Одна из них, которую я обнаружил после дальнейшего изучения, заключается в том, что ребра, которые раньше были направлены в одном направлении, правильно учитываются в степени узла. Osmnx представляет дороги с двусторонним движением как два ребра, по одному в каждом направлении, возможно, это и есть причина, если да, то почему край не отображается дважды. Мы будем благодарны за любую помощь в этом вопросе.

Ответы [ 2 ]

3 голосов
/ 17 июня 2020

Для справки: ответ здесь - использовать функцию OSMnx get_undirected для преобразования из MultiDiGraph в MultiGraph. Это позволяет избежать проблем, связанных с преобразованием ориентированного графа краев осевых линий дороги в неориентированный граф, где одно ребро представляет один физический сегмент дороги, включая обеспечение сохранения параллельных краев, если их геометрия различается. Эта функция является лучшим выбором в любое время, когда вы хотите получить представление ненаправленной уличной сети с помощью OSMnx.

2 голосов
/ 17 июня 2020

Это может быть потому, что ваш график направлен. Степень узла с 4 ребрами равна 4, но G.edges (узел) будет возвращать только те ребра, которые происходят от этого узла, а не те, которые указывают на него.

Вы можете получить доступ к ребрам, указывающим на узел, используя 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)

enter image description here

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)] []
...