如何从SimpleNamespace对象构建(稀疏)矩阵?

时间:2018-08-11 10:25:40

标签: python scipy namespaces sparse-matrix heatmap

我有一个SimpleNamespace对象的列表P。 P的第三个元素可能看起来像这样:

namespace(idx=2, values=[(0, 6), (4, 25), (7, 40), (11, 44), (13, 46), (20, 53)])

我想创建一个否则为0的矩阵,该矩阵在idx中的元组给定的所有坐标处都取值values(又名第4行,第25列的矩阵元素为2),最终将其馈入进入热图。什么是最 pythonic 方法?

在嵌套循环中提取元组和idx似乎在浪费SimpleNamespace类型。而且创建像dok_matrix这样的稀疏矩阵无论如何都不是那么有利,因为那样的话,您必须转换为热图(?)的适当矩阵

编辑:我的尝试(这很麻烦,并且会引发错误的BC热图,而不会采用dok_matrix)

from scipy.sparse import dok_matrix
import seaborn as sns

#P is a list of namespaces as shown above   
S = dok_matrix((10000, 10000), dtype=np.int32)
for i in range(len(P)):
    no_tuples = len(P[i].values)
    for j in range(no_tuples):
        S[P[i].values[j][0], P[i].values[j][1]] = P[i].idx
sns.heatmap(S)

1 个答案:

答案 0 :(得分:1)

要从您提供的样本中制作一个coo矩阵:

In [95]: from scipy import sparse

In [96]: idx = 2; values=[(0, 6), (4, 25), (7, 40), (11, 44), (13, 46), (20, 53)]

In [97]: data,row,col = [],[],[]

In [98]: row1,col1 = list(zip(*values))    
In [99]: row1
Out[99]: (0, 4, 7, 11, 13, 20)

In [101]: data.extend([idx for _ in range(len(row1))]) 
# or [idx]*len(row1)   
In [102]: row.extend(row1)    
In [103]: col.extend(col1)

对所有命名空间重复此操作。

In [104]: M = sparse.coo_matrix((data, (row, col)))
In [105]: M
Out[105]: 
<21x54 sparse matrix of type '<class 'numpy.int64'>'
    with 6 stored elements in COOrdinate format>

In [106]: M.A
Out[106]: 
array([[0, 0, 0, ..., 0, 0, 0],
       [0, 0, 0, ..., 0, 0, 0],
       [0, 0, 0, ..., 0, 0, 0],
       ...,
       [0, 0, 0, ..., 0, 0, 0],
       [0, 0, 0, ..., 0, 0, 0],
       [0, 0, 0, ..., 0, 0, 2]])

In [107]: M.data
Out[107]: array([2, 2, 2, 2, 2, 2])