将手动创建的 DOK 转换为 CSR

Convert manualy created DOK to CSR

对于机器学习任务,我需要一个 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 转换为 "real" DOK(发生以下错误):

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

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

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 样式输入(数据、行、列)。那些是原创风格,非常值得理解和使用。