Как создать матрицу смежности графа из словаря в python?

У меня есть следующий словарь:

g = {
'A': ['A', 'B', 'C'], 
'B': ['A', 'C', 'E'], 
'C': ['A', 'B', 'D'],
'D': ['C','E'],
'E': ['B','D']
}

Он реализует граф, каждый список содержит соседей вершин графа (ключи словаря — это сами вершины). У меня проблемы, я не могу придумать способ получить матрицу смежности графа из своих списков соседей, может быть, это легко, но я новичок в python, надеюсь, кто-нибудь может мне помочь! Я использую Python 3.5

Мне нужно создать следующую матрицу:

введите здесь описание изображения


person Patterson    schedule 20.05.2016    source источник
comment
Дополнительные пробелы в ключах/значениях преднамеренны? Как вы хотите получить доступ к результату? Подходит ли вложенный список? Если да, хотите ли вы, чтобы списки были в алфавитном порядке? (Ключи в словаре не гарантируют порядок.)   -  person Jared Goguen    schedule 20.05.2016
comment
Нет, пробелы были случайными, я отредактирую вопрос, чтобы исправить это! Я могу получить отсортированные ключи, используя: sorted (g)   -  person Patterson    schedule 20.05.2016


Ответы (2)


без панд

keys=sorted(g.keys())
size=len(keys)

M = [ [0]*size for i in range(size) ]

for a,b in [(keys.index(a), keys.index(b)) for a, row in g.items() for b in row]:
     M[a][b] = 2 if (a==b) else 1

M

[2, 1, 1, 0, 0],
[1, 0, 1, 0, 1],
[1, 1, 0, 1, 0],
[0, 0, 1, 0, 1],
[0, 1, 0, 1, 0]]

Пояснение

for a, row in g.items() перебирает записи ключ:значение в словаре, а for b in row перебирает значения. Если бы мы использовали (a,b), это дало бы нам все пары.

(keys.index(a), keys.index(b)) Но нам нужен индекс для присвоения соответствующей записи матрицы,

keys=sorted(g.keys()) вот почему мы извлекли и отсортировали ключи.

for a,b in... получение записей индекса и присвоение значения 1 или 2 на основе диагонального элемента или нет.

Матрица M = [ [0]*size for ... не может использоваться до инициализации.

person karakfa    schedule 20.05.2016
comment
Отлично, вы мне очень помогли! Но не могли бы вы объяснить мне этот код? Я плохо понял строку, в которой вы выполняете цикл, заполняющий массив, я знаю, что вы использовали понимание Python, но это сложно для меня, я новичок в Python, большое спасибо! - person Patterson; 21.05.2016
comment
Спасибо за ваше объяснение! Теперь это выглядит слишком просто! - person Patterson; 22.05.2016

Вот решение с использованием pandas.

import pandas as pd

g = {
'A': [ 'A', 'B', 'C'], 
'B': [ 'A', 'C', 'E'], 
'C': [ 'A', 'B ',' D '], # I added a comma here
'D': [' C ',' E '],
'E': [' B ',' D ']
}

# clean up the example
g = {k: [v.strip() for v in vs] for k, vs in g.items()}

edges = [(a, b) for a, bs in g.items() for b in bs]

df = pd.DataFrame(edges)

adj_matrix = pd.crosstab(df[0], df[1])

# 1  A  B  C  D  E
# 0               
# A  1  1  1  0  0
# B  1  0  1  0  1
# C  1  1  0  1  0
# D  0  0  1  0  1
# E  0  1  0  1  0

Я не уверен, почему у вас есть 2 в матрице вашего примера в позиции (A, A).

person hilberts_drinking_problem    schedule 20.05.2016
comment
Я считаю, что узлы, указывающие на себя, имеют вес 2 в этом взвешенном графе. Это всего лишь предположение. - person Vedang Mehta; 20.05.2016
comment
2 потому, что вершина «А» имеет ребро к себе - person Patterson; 20.05.2016
comment
Я не могу импортировать панд. ImportError: нет модуля с именем «панды» - person Patterson; 20.05.2016
comment
Вам нужно установить pandas или использовать другой метод. Пожалуйста, обратитесь сюда pandas.pydata.org Что касается матрицы: мы можем либо подсчитать исходящую степень, либо входную степень или и то, и другое. В первых двух случаях (A,A) указывает на единицу, в третьем случае остаток матрицы следует удвоить. Дайте мне знать, если я что-то упустил. - person hilberts_drinking_problem; 20.05.2016
comment
@Яким Пироженко Спасибо за ваше решение. У меня есть огромный набор данных, для которого потребуется 4 млн столбцов и 1 млн строк для adj_matrix . Итак, я получаю MemoryError на сервере. У вас есть решение? - person YNr; 24.02.2017
comment
@YNr, вы можете попробовать разреженную матрицу scipy или использовать график из пакета networkx с весами, представляющими количество ребер. - person hilberts_drinking_problem; 24.02.2017