Импорт неквадратной матрицы смежности в Networkx python - PullRequest
3 голосов
/ 22 января 2020

У меня есть некоторые данные в форме pandas формы данных ниже, где столбцы представляют дискретные навыки, а строки представляют дискретные задания. 1 присутствует, только если навык требуется заданием, в противном случае 0.

     skill_1, skill_2,
job_1      1,       0,       
job_2      0,       0,       
job_3      1,       1,       

Я хочу создать график, чтобы визуализировать эту связь между заданиями и навыками, используя networkx. Я пробовал два метода, один на самом фрейме данных, nx.from_pandas_adjacency и nx.from_numpy_matrix. Последний метод был применен к numpy представлению кадра данных, где были удалены имена столбцов и строк.

В любой ситуации возникла ошибка, поскольку это матрица non_square. Это имеет смысл, поскольку networkx, вероятно, интерпретирует и столбцы, и строки как один и тот же набор узлов. Однако столбцы и узлы представляют здесь совершенно разные вещи. Две работы связаны с навыками, которые они разделяют, и две навыки связаны с работой, которую они разделяют, но нет никаких прямых границ между любыми двумя навыками или любыми двумя работами.

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

Ответы [ 2 ]

1 голос
/ 22 января 2020

Один из вариантов - сгенерировать пропущенные строки и столбцы

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

df = pd.DataFrame({'skill_1': {'job_1': 1, 'job_2': 0, 'job_3': 1},
 'skill_2': {'job_1': 0, 'job_2': 0, 'job_3': 1}})

edges = df.columns

for i in df.index:
    df[i] = [0 for _ in range(len(df.index))]

for e in edges:
    df = df.append(pd.Series({c:0 for c in df.columns},name=e))

Что дает нам:

>>> df
         skill_1  skill_2  job_1  job_2  job_3
job_1          1        0      0      0      0
job_2          0        0      0      0      0
job_3          1        1      0      0      0
skill_1        0        0      0      0      0
skill_2        0        0      0      0      0

А затем мы можем прочитать в networkx, используя nx.from_pandas_adjacency (при условии, что вам нужен ориентированный граф)

G = nx.from_pandas_adjacency(df, create_using=nx.DiGraph)

В качестве альтернативы мы можем использовать df.stack ()

df = pd.DataFrame({'skill_1': {'job_1': 1, 'job_2': 0, 'job_3': 1},
 'skill_2': {'job_1': 0, 'job_2': 0, 'job_3': 1}})

G = nx.DiGraph()

for x,y in df.stack().reset_index().iterrows():
    G.add_node(y['level_0'])
    G.add_node(y['level_1'])
    if y[0]:
        G.add_edge(y['level_0'], y['level_1'])
0 голосов
/ 07 февраля 2020

У вас есть двудольный граф . Networkx может создать эту сеть из вашей исходной (bi) матрицы смежности, используя nx.algorithms.bipartite.matrix.from_biadjacency_matrix

...