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

在Python中将Sparse.LIL矩阵保存为csv,python,numpy,scipy,sparse-matrix,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 其中,值vij仅为非零值 是否有任何直接功能可以做到这一点?我怀疑,一个元素一个元素地做会非常昂贵 稀疏矩阵格式只存储非零值,因此

我有一个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
其中,值vij仅为非零值


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

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

但是
coo
格式将其数据存储在3个属性中,即行、列和数据,这是您想要的值

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')
写入两个整数列和一个浮点

如果您不喜欢编写的某些整数索引值,我们可能需要将
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