У меня есть данные в виде:
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 довольно запутанно.
Данные должны быть в списке, чтобы построить график
Не могли бы вы объяснить, как вы получаете значения на графике 0, 10, 15, 20...
Данные хранятся в файле?
Это случайные значения, я просто использовал эти числа в качестве примера @TheRavenSpectre
@user2246849 user2246849 Да, данные хранятся в отдельном файле, который я планирую импортировать до того, как произойдет преобразование.
Не могли бы вы затем предоставить фактические данные / меньшую выборку данных и конечный результат, который вы хотите, поскольку это позволяет нам лучше понять, чего вы хотите.






Вы можете сделать это следующим образом:
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 согласно вашему файлу.
Вы знаете, как я мог пропустить чтение первой строки файла?
@AngelaRubchinksy Я отредактировал свой ответ, чтобы пропустить строку (см. skip_rows).
Вы можете использовать словарь, чтобы составить список смежности. Затем перечислите ключи этого словаря, чтобы определить индекс для каждого ключа. Затем, наконец, скопируйте веса в окончательную матричную структуру:
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)
Вы хотите, чтобы данные были списком или строкой, содержащей определение списка внутри?