Python 中 pandas 数据帧的邻接矩阵

Adjacency matrix from pandas dataframe in Python

下面是我在 python 中尝试做的一个小例子。 我正在使用网络,在我的网络中有 15000 个不同的节点。 数据来自 pandas 数据集:

Node Target  Node_Attrib
mom    dad       0.2
mom    grandmother 0.12
mom    grandfather 0.24
mom    Lucy      0.2
dad    mom       0.4
dad    Lucy      0.3
Lucy   mom       0.1
Lucy   dad       0.3
Lucy   Mark      0.1
Lucy   grandmother 0.2
Lucy   grandfather 0.1

网络创建如下:

G=nx.from_pandas_edgelist(df,’Node’, ‘Target’,[‘Node_Attrib’]

其中 nx 是网络 x。 由于我想进行一些分析,因此需要使用邻接矩阵。 我正在考虑使用交叉表来做到这一点:

adj = pd.crosstab(df.Node, df.Target)
idx=adj.columns.union(df.index)
adj=adj.reindex(index=idx,columns=idx,fill_value=0)

我想知道这是否是在 python 中获取邻接矩阵的最佳方法,这也是由于网络中的节点数量。 您是否知道可以更好地管理 Python 中数千个节点(和边缘)的不同方法?

首先,nx.from_pandas_edgelist()会默认创建一个无向图。这意味着它首先将边 (mom, Lucy) 的值设置为 0.2,因为这是您第一次在 table 中遇到该边。但是当你解析(Lucy, mom)时,同一条边会被更新为新值

>>> G.get_edge_data('mom', 'Lucy')
{'Node_Attrib': 0.1}

对于有向图,将行更改为

G = nx.from_pandas_edgelist(df, 'Node', 'Target', ['Node_Attrib'], create_using=nx.DiGraph())

Networkx 具有创建 scipy 稀疏矩阵的函数 nx.adjacency_matrix()。当并非所有边都有值时,这对于节省内存很有用。

>>> adj = nx.adjacency_matrix(G, weight='Node_Attrib')
>>> adj[0,1]    # (mom, dad) edge as the node ordering is taken from `G.nodes`
0.2
>>> array = adj.todense()   # if for some reason you need the whole matrix

正如该函数的文档所述,您还可以创建一个纯 Python 等效于带有字典的稀疏矩阵。但是如果你想进行一些分析,我怀疑上面的数组选项对你来说更合适table。

>>> adj = nx.convert.to_dict_of_dicts(G)
>>> adj['mom']['Lucy']['Node_Attrib']
0.2

这需要一些清理工作,以便 adj[node1][node2] 直接为您提供边缘值。您还需要实际将它与 adj.get(node1, {}).get(node2, 0.) 一起使用,而不是 运行 进入任何 KeyError.