我试图通过一个非常大的元组列表来表示邻接矩阵。我如何在numpy矩阵或scipy.sparse矩阵中表示此列表,以便使用像igraph或networkx这样的包?
[('b', 'c'),
('b', 'a'),
('c', 'd'),
('c', 'a'),
('c', 'b'),
('a', 'b'),
('a', 'c')]
我很抱歉,如果这是重复的,但我找不到任何关于如何将非数字元组转换为邻接矩阵的文档。
答案 0 :(得分:4)
您可以使用np.unique
将节点转换为索引:
>>> adj = [('b', 'c'),
... ('b', 'a'),
... ('c', 'd'),
... ('c', 'a'),
... ('c', 'b'),
... ('a', 'b'),
... ('a', 'c')]
>>> node_names, adj_idx = np.unique(adj, return_inverse=True)
>>> node_names
array(['a', 'b', 'c', 'd'],
dtype='|S1')
>>> adj_idx = adj_idx.reshape(-1, 2)
>>> adj_idx
array([[1, 2],
[1, 0],
[2, 3],
[2, 0],
[2, 1],
[0, 1],
[0, 2]])
由此可以构建密集邻接矩阵:
>>> adj_matrix = np.zeros((len(node_names),)*2)
>>> adj_matrix[adj_idx[:, 0], adj_idx[:, 1]] = 1
>>> adj_matrix
array([[ 0., 1., 1., 0.],
[ 1., 0., 1., 0.],
[ 1., 1., 0., 1.],
[ 0., 0., 0., 0.]])
或者采用稀疏格式:
>>> sps_adj_mat = sps.coo_matrix((np.ones(shape=(len(adj_idx),)),
... (adj_idx[:, 0], adj_idx[:, 1])),
... shape=(len(node_names),)*2)
>>> sps_adj_mat
<4x4 sparse matrix of type '<type 'numpy.float64'>'
with 7 stored elements in COOrdinate format>
>>> sps_adj_mat.A
array([[ 0., 1., 1., 0.],
[ 1., 0., 1., 0.],
[ 1., 1., 0., 1.],
[ 0., 0., 0., 0.]])
答案 1 :(得分:2)
NetworkX可以包含非数字节点。如果我正确理解您的问题,您可以像在网络图表中一样轻松地使用它:
import networkx as nx
g = nx.Graph([('a', 'b'), ('c', 'd'), ...])
您是否在询问如何将其转换为scipy.sparse
或numpy
矩阵?或者您希望它与graph和networkx一起使用吗?