Преобразование весов графика в матрицу в python

У меня есть данные в виде:

A=B=11
A=C=6
A=D=5
B=C=19
B=D=17
C=D=6

Но я хотел бы преобразовать это в этот формат:

graph= [[ 0, 10, 15, 20 ],
            [ 10, 0, 35, 25 ],
            [ 15, 35, 0, 30 ],
            [ 20, 25, 30, 0 ]]

Как это достигается? Я знаю, как работают многомерные массивы, однако построение этой матрицы с использованием python довольно запутанно.

Вы хотите, чтобы данные были списком или строкой, содержащей определение списка внутри?

Ann Zen 14.05.2022 17:21

Данные должны быть в списке, чтобы построить график

Angela Rubchinksy 14.05.2022 17:23

Не могли бы вы объяснить, как вы получаете значения на графике 0, 10, 15, 20...

TheRavenSpectre 14.05.2022 17:25

Данные хранятся в файле?

user2246849 14.05.2022 17:26

Это случайные значения, я просто использовал эти числа в качестве примера @TheRavenSpectre

Angela Rubchinksy 14.05.2022 17:30

@user2246849 user2246849 Да, данные хранятся в отдельном файле, который я планирую импортировать до того, как произойдет преобразование.

Angela Rubchinksy 14.05.2022 17:31

Не могли бы вы затем предоставить фактические данные / меньшую выборку данных и конечный результат, который вы хотите, поскольку это позволяет нам лучше понять, чего вы хотите.

TheRavenSpectre 14.05.2022 17:33
"Это случайные значения": чем это полезно? Не могли бы вы предоставить ввод и вывод, которые связаны друг с другом?
trincot 14.05.2022 17:37
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
0
8
35
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Вы можете сделать это следующим образом:

import pandas as pd
import numpy as np

# Change to your filename.
filename = 'graph.csv'

# Lines to skip.
skip_rows = 1

# Whether the graph is undirected. 
undirected = True

# Read file and convert vertex names to integer indices. Names are sorted. 
# I.e., A=0, B=1, etc. (like in your example).
df = pd.read_csv(filename, sep='=', header=None, names=['n1', 'n2', 'weight'], skiprows=skip_rows)
cat_type = pd.CategoricalDtype(categories=sorted(np.unique(np.concatenate((df['n1'].unique(), df['n2'].unique())))), ordered=True)
df['n1'] = df['n1'].astype(cat_type).cat.codes
df['n2'] = df['n2'].astype(cat_type).cat.codes

n_nodes = len(cat_type.categories)
graph = np.full((n_nodes, n_nodes), np.nan)

for n1, n2, w in zip(df['n1'], df['n2'], df['weight']):
    graph[n1, n2] = w
    if undirected:
        graph[n2, n1] = w

np.fill_diagonal(graph, 0)

print(graph)
[[ 0. 11.  6.  5.]
 [11.  0. 19. 17.]
 [ 6. 19.  0.  6.]
 [ 5. 17.  6.  0.]]

Если graph[i, j] == NaN, это означает, что нет ребра (пути длины 1) от узла i к узлу j согласно вашему файлу.

Вы знаете, как я мог пропустить чтение первой строки файла?

Angela Rubchinksy 14.05.2022 18:15

@AngelaRubchinksy Я отредактировал свой ответ, чтобы пропустить строку (см. skip_rows).

user2246849 14.05.2022 18:16
Ответ принят как подходящий

Вы можете использовать словарь, чтобы составить список смежности. Затем перечислите ключи этого словаря, чтобы определить индекс для каждого ключа. Затем, наконец, скопируйте веса в окончательную матричную структуру:

nodes = {}
for line in open("input.txt").read().splitlines():
    a, b, weight = line.split(" = ")
    nodes.setdefault(a, []).append((b, int(weight)))
    nodes.setdefault(b, []).append((a, int(weight)))

n = len(nodes)
key2index = { key: i for i, key in enumerate(nodes.keys()) }
graph = [[0] * n for _ in range(n)]
for a, edges in nodes.items():
    row = graph[key2index[a]]
    for b, weight in edges:
        row[key2index[b]] = weight

print(graph)

Ноль в матрице означает, что ребра нет, как в вашем примере на главной диагонали матрицы (т.е. в вашем примере на графике нет «петлей»).

Комментарий

Как вы просили в удаленном комментарии пропустить первую строку файла, вот код, адаптированный именно для этого:

nodes = {}
lines = open("input.txt").read().splitlines()
for line in lines[1:]:
    a, b, weight = line.split(" = ")
    nodes.setdefault(a, []).append((b, int(weight)))
    nodes.setdefault(b, []).append((a, int(weight)))

n = len(nodes)
key2index = { key: i for i, key in enumerate(nodes.keys()) }
graph = [[0] * n for _ in range(n)]
for a, edges in nodes.items():
    row = graph[key2index[a]]
    for b, weight in edges:
        row[key2index[b]] = weight

print(graph)

Другие вопросы по теме