我有一个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创建的数据值是float。并且A数组也是float的。所以我可以用浮点格式保存,例如。 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

08-24 17:49