将手动创建的DOK转换为CSR

时间:2019-05-26 23:18:38

标签: python scipy sparse-matrix

对于机器学习任务,我需要CSR格式的稀疏矩阵。 首先,我手动构建一个DOK,如下所示(基于this guid):

dok = { (0,0): 1, (0,9): 1, (5,12): 1}
#the value is always 1
#the keys representing the position in the matrix
#my DOK has around 6 million entries like these

我知道要将其格式化为CSR。如果我理解docs是正确的,则只有在我的输入也是稀疏矩阵的情况下才有可能。但是我的DOK不能像字典一样被识别为稀疏矩阵。我也无法将DOK转换为“真实的” DOK(发生以下错误):

TypeError: Expected rank <=2 dense array or matrix.

那我如何将我的DOK转换为CSR?

1 个答案:

答案 0 :(得分:0)

In [472]: dok = { (0,0): 1, (0,9): 1, (5,12): 1}  

制作一个空白的dok矩阵:

In [473]: M = sparse.dok_matrix((20,20), dtype=int)                                                   
In [474]: M                                                                                           
Out[474]: 
<20x20 sparse matrix of type '<class 'numpy.int64'>'
    with 0 stored elements in Dictionary Of Keys format>

M是Python字典的子类。过去,我们可以使用字典.update方法从Python字典中有效地添加新值,但是该方法已被禁用(尝试查看错误消息)。但是提供了后门:

In [475]: M._update(dok)                                                                              
In [476]: M                                                                                           
Out[476]: 
<20x20 sparse matrix of type '<class 'numpy.int64'>'
    with 3 stored elements in Dictionary Of Keys format>

_update有一个警告注释,未检查值,请谨慎使用。

一旦您拥有dok格式,就可以将其转换为csr格式:

In [477]: M1=M.tocsr()                                                                                
In [478]: M1                                                                                          
Out[478]: 
<20x20 sparse matrix of type '<class 'numpy.int64'>'
    with 3 stored elements in Compressed Sparse Row format>
In [479]: M1.A                                                                                        
Out[479]: 
array([[1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 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, 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],
       [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, 1, 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, 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]],
      dtype=int64)

如果在定义dok时出错,它可能会显示在csr转换中。

另一种选择是遍历dok并构造相应的coo样式输入(数据,行,列)。这些是原始样式,非常值得理解和使用。