从字典创建稀疏矩阵

时间:2017-04-12 23:43:38

标签: python dictionary matrix minimum-spanning-tree

我正在做一个学校项目,我得到了一个无向图G.我应该找到G中的最小生成树。我想我会使用Scipy (https://docs.scipy.org/doc/scipy-0.14.0/reference/generated/scipy.sparse.csgraph.minimum_spanning_tree.html)中的minimum_spanning_tree。但要做到这一点,我必须提供一个array_like或稀疏矩阵,2维。 像这样:

x_right=
    ([[0, 2, 0],
    [2, 0, 5],
    [0, 5, 0]])

在项目中,我应该接受如下结构的邻接列表:

x_input=
    {'A': [('B', 2)],
     'B': [('A', 2), ('C', 5)], 
     'C': [('B', 5)]}

尝试一下......看看minimum_spanning_tree是否给出了我想要的结果,我通过手动将x_input更改为x_right来运行它,并得到输出:

(0, 1)    2.0
(1, 2)    5.0

这是我想要的,但我应该以与x_input相同的格式返回输出。

我一直在尝试各种方法(其中一个是DictVectorizer - ValueError:无法将字符串转换为浮点数:'B'......就像在其他情况下一样)很长时间以来我认为是时候寻找帮助

所以要简化一下,你有什么建议我可以从x_input创建一个适合minimum_spanning_tree的矩阵(以及如何将结果再次转换为x_input格式)。

由于

1 个答案:

答案 0 :(得分:3)

不确定我是否完全理解这个问题。我得到的是您想要将x_input转换为稀疏矩阵x_right

import scipy.sparse as sp

x_input= {'A': [('B', 2)],
          'B': [('A', 2), ('C', 5)], 
          'C': [('B', 5)]}

keys = x_input.keys()
map_dict = dict(zip(list(keys), range(len(keys))))

我创建字典键以将值映射到上面的索引,例如从A1B2。然后,您可以循环遍历给定的字典以获取行/列位置。之后,您可以将矩阵的行/列对与相应的值转换为稀疏矩阵。

rows, cols, vals = [], [], []
for key, values in x_input.items():
    for value in values:
        rows.append(map_dict[key])
        cols.append(map_dict[value[0]])
        vals.append(value[1])
X = sp.csr_matrix((vals, (rows, cols)))

输出如下:

print(X.toarray())
array([[0, 2, 0],
       [2, 0, 5],
       [0, 5, 0]], dtype=int64)

要转换稀疏矩阵,简单的方法是将稀疏CSR矩阵转换为COO矩阵。 COO矩阵允许您轻松获取行,列和数据。获取行/列位置后,我有字典map_dict_reverse将这些字符转换回给定的键。

from collections import defaultdict
map_dict_reverse = dict(zip(range(len(keys)), list(keys)))

Xcoo = X.tocoo() # convert csr matrix to coo sparse matrix
x_convert = defaultdict(list)
for (r, c, d) in zip(Xcoo.row, Xcoo.col, Xcoo.data):
    x_convert[map_dict_reverse[r]].append((map_dict_reverse[c] , d))
x_convert = dict(x_convert)

最后你会得到x_input

{'A': [('B', 2)], 'B': [('A', 2), ('C', 5)], 'C': [('B', 5)]}