我有一个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