为网络绘图转换数据帧

2024-05-18 05:37:58 发布

您现在位置:Python中文网/ 问答频道 /正文

我有这样一个数据帧:

ID  | Node 1 | Node 2 | Node 3
a   |   1    |    0   |   1
b   |   0    |    1   |   1
c   |   1    |    0   |   0
d   |   1    |    1   |   1
e   |   0    |    1   |   1

我想更改它,以便可以将其转换为网络图,其中节点之间的连接是为两个节点指示ID的次数:

^{pr2}$

Tags: 数据idnode节点次数网络图pr2
3条回答

Tai's solution为基础, 您可以使用

import numpy as np
import pandas as pd

def get_weights(df):
    df2 = df.filter(regex='Node')
    nodes = df2.columns
    arr = df2.values
    m = np.dot(arr.T, arr).astype(float)
    idx = np.tril_indices(m.shape[0])   
    m[idx] = np.nan
    result = pd.DataFrame(m, columns=nodes, index=nodes)
    result = result.stack()
    result = result.astype(int)
    result = result.reset_index()
    result.columns = ['Node A', 'Node B', 'Weights']
    return result

df = pd.DataFrame({'ID': ['a', 'b', 'c', 'd', 'e'],
 'Node 1': [1, 0, 1, 0, 0],
 'Node 2': [0, 1, 0, 1, 1],
 'Node 3': [1, 1, 0, 1, 1]})
result = get_weights(df)
print(result)

它产生了

^{pr2}$

邻接矩阵的数据帧

您可以迭代数据帧以创建numpy数组:

import pandas as pd
import numpy as np
from itertools import combinations
import networkx as nx

df = pd.DataFrame({'node_1': [1,0,1,1,0], 
                   'node_2':[0,1,0,1,1], 
                   'node_3':[1,1,0,1,1]})

# Array dimension
l = len(df.columns)
# empty matrice
mat = np.zeros((l,l))

for i, row in df.iterrows():
    positions = np.where(row)[0]
    if len(positions)>1:
        for comb in combinations(positions,2):
            i,j = comb
            mat[i,j] += 1
            mat[j,i] += 1

mat

array([[ 0., 1., 2.], [ 1., 0., 3.], [ 2., 3., 0.]])

numpy邻接矩阵的Networkx图

^{pr2}$

[输出]:EdgeDataView([(0, 1, {'weight': 1.0}), (0, 2, {'weight': 2.0}), (1, 2, {'weight': 3.0})])

而不是使用边缘列表表单

Node A | Node B | Weight |
Node 1 | Node 2 |    1   |
Node 1 | Node 3 |    2   |
Node 2 | Node 3 |    3   |

您还可以计算共现/邻接矩阵来表示您感兴趣的关系。它可以用点积构造。阿尔科已经在《熊猫》杂志上给出了答案

我用numpy修改alko的答案

^{pr2}$

我不喜欢alko的答案之一是它试图通过改变df.values来改变数据帧的对角线部分,比如df。不应升级直接更改df.values以更改df,因为有时{}返回一个副本,而有时返回一个视图。有关详细信息,请参阅我前面的问题Will changes in DataFrame.values always modify the values in the data frame?。在

如果想要遵循alko的pandas方法,可以用

df = df - np.eye(len(df)) * np.diagonal(df)

相关问题 更多 >