从带行列头的CSV文件读取networkx图

4 投票
2 回答
9170 浏览
提问于 2025-04-18 13:23

我有一个CSV文件,这个文件表示一个图的邻接矩阵。不过,这个文件的第一行和第一列都是节点的标签。我该如何把这个文件读入到一个networkx图对象中呢?有没有什么简单的Python方法可以做到,而不需要绕来绕去?

我目前的尝试:

x = np.loadtxt('file.mtx', delimiter='\t', dtype=np.str)
row_headers = x[0,:]
col_headers = x[:,0]
A = x[1:, 1:]
A = np.array(A, dtype='int')

但这当然不能解决问题,因为在创建图的时候我需要节点的标签。

数据的例子:

Attribute,A,B,C
A,0,1,1
B,1,0,0
C,1,0,0

这里的分隔符是制表符,而不是逗号。

2 个回答

2

这个方法是可行的,不过我不确定它是不是最好的办法:

In [23]:

import pandas as pd
import io
import networkx as nx
temp = """Attribute,A,B,C
A,0,1,1
B,1,0,0
C,1,0,0"""
# for your case just load the csv like you would do, use sep='\t'
df = pd.read_csv(io.StringIO(temp))
df
Out[23]:
  Attribute  A  B  C
0         A  0  1  1
1         B  1  0  0
2         C  1  0  0

In [39]:

G = nx.DiGraph()
for col in df:
    for x in list(df.loc[df[col] == 1,'Attribute']):
        G.add_edge(col,x)

G.edges()
Out[39]:
[('C', 'A'), ('B', 'A'), ('A', 'C'), ('A', 'B')]

In [40]:

nx.draw(G)

在这里输入图片描述

4

你可以把数据读入一个有结构的数组里。你可以通过 x.dtype.names 来获取标签,然后可以使用 nx.from_numpy_matrix 来生成 networkx 图。

import numpy as np
import networkx as nx
import matplotlib.pyplot as plt

# read the first line to determine the number of columns
with open('file.mtx', 'rb') as f:
    ncols = len(next(f).split('\t'))

x = np.genfromtxt('file.mtx', delimiter='\t', dtype=None, names=True,
                  usecols=range(1,ncols) # skip the first column
                  )
labels = x.dtype.names

# y is a view of x, so it will not require much additional memory
y = x.view(dtype=('int', len(x.dtype)))

G = nx.from_numpy_matrix(y)
G = nx.relabel_nodes(G, dict(zip(range(ncols-1), labels)))

print(G.edges(data=True))
# [('A', 'C', {'weight': 1}), ('A', 'B', {'weight': 1})]

nx.from_numpy_matrix 这个函数有一个 create_using 参数,你可以用它来指定你想创建的 networkx 图的类型。例如,

G = nx.from_numpy_matrix(y, create_using=nx.DiGraph())

这样就会把 G 变成一个 DiGraph(有向图)。

撰写回答