在Python中将Sparse.LIL矩阵保存到csv

时间:2016-05-20 04:20:30

标签: python numpy scipy sparse-matrix

我有一个0.15M x 1.3M的sparse.lil矩阵,我希望将其存储在csv文件中。如何将其保存在csv文件中,以使得生成的文件大小最小。据我所知,最好的方法是将其存储为

# output.csv

row1 col1 v11
row1 col2 v12
row1 col7 v17
row1 col9 v19
row2 col3 v23
row2 col6 v26

其中值v ij 仅为非零值。

是否有任何直接功能可以做到这一点?我怀疑,逐个元素的做法将非常昂贵!

1 个答案:

答案 0 :(得分:3)

稀疏矩阵格式只存储非零值,因此写入这些值将是最紧凑的选项。但lil是列表格式列表,不是您要编写的格式。

coo格式将其数据存储在3个属性,row,col和data中,这些是您想要的值。

scipy.io具有处理稀疏的savemat格式,但它是一个MATLAB样式的文件。我不熟悉scipy.io中的其他选项。

值是否为整数?这将是最简单的。在这里,我将coo格式的3个属性数组连接成Nx3数组,然后将其保存到通常为np.savetxt的文本文件中。

In [649]: M = sparse.eye(10).tolil()

In [650]: Mc = M.tocoo()

In [651]: Mc.row,Mc.col,Mc.data
Out[651]: 
(array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9], dtype=int32),
 array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9], dtype=int32),
 array([ 1.,  1.,  1.,  1.,  1.,  1.,  1.,  1.,  1.,  1.]))

In [652]: A=np.column_stack((Mc.row,Mc.col,Mc.data))

In [653]: A.shape
Out[653]: (10, 3)

In [655]: np.savetxt('lil.txt',A, fmt='%5.d',delimiter=',')

In [656]: cat lil.txt
    0,    0,    1
    1,    1,    1
    2,    2,    1
    ...
    7,    7,    1
    8,    8,    1
    9,    9,    1

形成阵列会很快。编写它需要时间,因为np.savetxt遍历数组行,并逐行写入。但面对它,所有文本文件都是逐行写的,对吗?

 f.write(fmt % tuple(row))

这是lil数组的格式:

In [658]: M.rows
Out[658]: array([[0], [1], [2], [3], [4], [5], [6], [7], [8], [9]], dtype=object)

In [659]: M.data
Out[659]: array([[1.0], [1.0], [1.0], [1.0], [1.0], [1.0], [1.0], [1.0], [1.0], [1.0]], dtype=object)

实际上由M创建的数据值是浮点数。 A数组也是浮点数。所以我可以用浮动格式保存,例如。 np.savetxt('lil.txt',A, fmt='%10.5f',delimiter=',')

np.savetxt('lil.txt',A, fmt='%10d,%10d,%10.5f')写入2个整数列和一个浮点数。

如果你不喜欢写的一些整数索引值,我们可能需要将A形成为结构化数组。

====================

另一个选择是直接写行。根据我所知的np.savetxt,这可能同样快。

In [678]: with open('lil.txt','wb') as f:
    for x in zip(Mc.row,Mc.col,Mc.data):
        f.write(b'%5d,%5d,%10f\n'%x)
   .....:         

In [679]: cat lil.txt
    0,    0,  1.000000
    1,    1,  1.000000
    2,    2,  1.000000
    ...
    8,    8,  1.000000
    9,    9,  1.000000