我正在将numpy稀疏数组(压缩)保存到csv中。结果是我有一个3GB的CSV。问题是95%的单元格为0.0000。我用过fmt='%5.4f'。如何格式化和保存,使零仅保存为0,非零浮点数与'%5.4f'格式一起保存?如果可以的话,我敢肯定我可以将3GB降低到300MB。
numpy
fmt='%5.4f'
'%5.4f'
我在用
np.savetxt('foo.csv', arrayDense, fmt='%5.4f', delimiter = ',')
感谢和问候
如果看一下的源代码np.savetxt,您会看到,虽然有很多代码可以处理参数以及Python 2和Python 3之间的差异,但最终它还是一个简单的遍历行的python循环,其中每行被格式化并写入文件。因此,如果您自己编写,就不会失去任何性能。例如,这是一个精简的函数,它写入紧凑的零:
np.savetxt
def savetxt_compact(fname, x, fmt="%.6g", delimiter=','): with open(fname, 'w') as fh: for row in x: line = delimiter.join("0" if value == 0 else fmt % value for value in row) fh.write(line + '\n')
例如:
In [70]: x Out[70]: array([[ 0. , 0. , 0. , 0. , 1.2345 ], [ 0. , 9.87654321, 0. , 0. , 0. ], [ 0. , 3.14159265, 0. , 0. , 0. ], [ 0. , 0. , 0. , 0. , 0. ], [ 0. , 0. , 0. , 0. , 0. ], [ 0. , 0. , 0. , 0. , 0. ]]) In [71]: savetxt_compact('foo.csv', x, fmt='%.4f') In [72]: !cat foo.csv 0,0,0,0,1.2345 0,9.8765,0,0,0 0,3.1416,0,0,0 0,0,0,0,0 0,0,0,0,0 0,0,0,0,0
然后,只要编写自己的savetxt函数,就可以使其处理稀疏矩阵,因此不必在保存之前将其转换为(密集)numpy数组。(我假设稀疏数组是使用from中的稀疏表示形式实现的scipy.sparse。)在以下函数中,唯一的变化是from... for value in row到... for value in row.A[0]。
savetxt
scipy.sparse
... for value in row
... for value in row.A[0]
def savetxt_sparse_compact(fname, x, fmt="%.6g", delimiter=','): with open(fname, 'w') as fh: for row in x: line = delimiter.join("0" if value == 0 else fmt % value for value in row.A[0]) fh.write(line + '\n')
例:
In [112]: a Out[112]: <6x5 sparse matrix of type '<type 'numpy.float64'>' with 3 stored elements in Compressed Sparse Row format> In [113]: a.A Out[113]: array([[ 0. , 0. , 0. , 0. , 1.2345 ], [ 0. , 9.87654321, 0. , 0. , 0. ], [ 0. , 3.14159265, 0. , 0. , 0. ], [ 0. , 0. , 0. , 0. , 0. ], [ 0. , 0. , 0. , 0. , 0. ], [ 0. , 0. , 0. , 0. , 0. ]]) In [114]: savetxt_sparse_compact('foo.csv', a, fmt='%.4f') In [115]: !cat foo.csv 0,0,0,0,1.2345 0,9.8765,0,0,0 0,3.1416,0,0,0 0,0,0,0,0 0,0,0,0,0 0,0,0,0,0