我有一个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 仅为非零值。
是否有任何直接功能可以做到这一点?我怀疑,逐个元素的做法将非常昂贵!
答案 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