NetworkX - Создать график из узла и атрибутов
Я пытаюсь сделать сетевой график, используя networkX, который получает узлы и атрибуты. Каждый узел уникален, но может иметь соответствующие атрибуты с другими узлами. Эти атрибуты будут действовать как ребра между узлами, которые имеют этот же атрибут.
Пример ввода (узел и атрибуты)
Name1 2-s2.0-84905590088, 2-s2.0-84901477890
Name2 2-s2.0-84941169876
Name3 2-s2.0-84958012773
Name4 2-s2.0-84960796474
Name5 2-s2.0-84945302996, 2-s2.0-84953281823, 2-s2.0-84944268402, 2-s2.0-84949478621, 2-s2.0-84947281259, 2-s2.0-84947759580, 2-s2.0-84945265895, 2-s2.0-84945247800, 2-s2.0-84946541351, 2-s2.0-84946051072, 2-s2.0-84942573284, 2-s2.0-84942280140, 2-s2.0-84937715425, 2-s2.0-84943751990, 2-s2.0-84957729558, 2-s2.0-84938844501, 2-s2.0-84934761065
Name6 2-s2.0-84908333808
Name7 2-s2.0-84925879816
Name8 2-s2.0-84940447040, 2-s2.0-84949534001
Name9 2-s2.0-84899915556, 2-s2.0-84922392381, 2-s2.0-84905079505, 2-s2.0-84940931972, 2-s2.0-84893682063, 2-s2.0-84954285577, 2-s2.0-84934934228, 2-s2.0-84926624187
Name10 2-s2.0-84907065810
так Name5
будет иметь много ребер, которые связаны с другими именами с тем же идентификатором.
Я не уверен, что это правильная идея, стоящая за networkX, или вы можете даже использовать этот вид ввода для графика. Если этот способ недостижим, как бы я отформатировал ввод для создания этого графика? Я не смог найти никакой документации или видео об использовании networkX таким образом.
1 ответ
То, что вы спрашиваете, возможно. Я сохранил ваши данные в файле CSV - обратите внимание, что я добавил ,
после того, как имена узлов и что я удалил все пробелы.
Name1,2-s2.0-84905590088,2-s2.0-84901477890
Name2,2-s2.0-84941169876
Name3,2-s2.0-84958012773
Name4,2-s2.0-84960796474
Name5,2-s2.0-84945302996,2-s2.0-84953281823,2-s2.0-84944268402,2-s2.0-84949478621,2-s2.0-84947281259,2-s2.0-84947759580,2-s2.0-84945265895,2-s2.0-84945247800,2-s2.0-84946541351,2-s2.0-84946051072,2-s2.0-84942573284,2-s2.0-84942280140,2-s2.0-84937715425,2-s2.0-84943751990,2-s2.0-84957729558,2-s2.0-84938844501,2-s2.0-84934761065
Name6,2-s2.0-84908333808
Name7,2-s2.0-84925879816
Name8,2-s2.0-84940447040,2-s2.0-84949534001
Name9,2-s2.0-84899915556,2-s2.0-84922392381,2-s2.0-84905079505,2-s2.0-84940931972,2-s2.0-84893682063,2-s2.0-84954285577,2-s2.0-84934934228,2-s2.0-84926624187
Name10,2-s2.0-84907065810
Одно наблюдение: вы говорите, что Name5
будет иметь много краев, но его атрибуты уникальны. Более того, когда я запускаю свой код с вашими данными, оказывается, что все атрибуты уникальны, поэтому на графике нет ребер.
Я настроил ваши данные так, чтобы я использовал только первые 12 символов каждого атрибута (я делаю это со строкой new_attributes = [x[:12] for x in new_attributes]
). Таким образом, я получаю некоторые подходящие атрибуты.
Теперь код:
import networkx as nx
import csv
G = nx.Graph()
with open('data.csv') as csvfile:
csv_reader = csv.reader(csvfile, delimiter=',')
for row in csv_reader:
new_node = row[0] # first element in row
new_attributes = row[1:] # whole row except the first element
new_attributes = [x[:12] for x in new_attributes] # remove this for your data!
# add the node and its attributes to the graph
G.add_node(new_node, my_attributes=new_attributes) # attributes are stored as a list
# add edges based on existing nodes
for node, attrs in G.nodes(data=True):
# skip node we just added
if node != new_node:
for attr in attrs['my_attributes']:
# check if any of the attributes for `node` are also in the `new_attributes` list
if attr in new_attributes:
G.add_edge(node, new_node)
for edge in G.edges():
print('EDGE:', edge, '| COMMON ATTRIBUTES:', set(G.node[edge[0]]['my_attributes']) & set(G.node[edge[1]]['my_attributes']))
Для каждой строки CSV я добавляю узел (с его атрибутами) к графу и на основе текущих узлов в графе (и их атрибутов) я добавляю ребра. Обратите внимание, что атрибуты узла хранятся в списке и доступны с помощью my_attributes
ключ. В конце я также печатаю ребра с соответствующими атрибутами для узлов в конкретном ребре (я использую set
а также &
чтобы получить пересечение двух списков атрибутов).
Вывод для настроенных данных:
EDGE: ('Name5', 'Name9') | COMMON ATTRIBUTES: {'2-s2.0-84934'}
EDGE: ('Name5', 'Name8') | COMMON ATTRIBUTES: {'2-s2.0-84949'}
EDGE: ('Name8', 'Name9') | COMMON ATTRIBUTES: {'2-s2.0-84940'}
EDGE: ('Name1', 'Name9') | COMMON ATTRIBUTES: {'2-s2.0-84905'}
Последнее замечание: если вам нужно иметь несколько ребер между двумя узлами, используйте MultiGraph
,