在python中加速大型矩阵序列化?

时间:2015-02-17 16:44:03

标签: python matrix io scipy

在python(2.7)中,我试图加速将一些非常大的矩阵序列化为基于行的格式(这些格式在序列化时大约为2-5亿行)。

输出格式为<row> <col> <value>\n,其中row和col为整数,value为浮点数,例如:

0 0 0.4
0 1 1.2
...
12521 5498 0.456
12521 5499 0.11

输入数据为scipy.sparse.coo_matrix,目前使用以下序列进行序列化:

from __future__ import print_function
from __future__ import unicode_literals

import itertools

# ...code to generate 'matrix' variable skipped ...

with open('outfile', 'w') as fh:
    for i, j, v in itertools.izip(matrix.row, matrix.col, matrix.data):
        print(b"{} {} {}".format(i, j, v), file=fh)

根据输入矩阵,这可能需要几个小时才能运行,因此即使将写入时间减少10%也会节省大量时间。

1 个答案:

答案 0 :(得分:2)

Pandas似乎有点快(你可能想把它应用于固定大小的块,因为它显然最终会复制数据,以避免大量内存使用)

df = pandas.DataFrame(dict(row=row, col=col, value=value),
                      columns=['row', 'col', 'value'], 
                      copy=False)
df.to_csv('outfile', sep=' ', header=False, index=False)

然而,更快的选择是用Cython编写的低级转储例程。

from libc.stdio cimport fprintf, fopen, FILE, fclose

def dump_array(bytes filename, long[:] row, long[:] col, double[:] value):
    cdef FILE *fh
    cdef Py_ssize_t i, n

    n = row.shape[0]

    fh = fopen(filename, "w")
    if fh == NULL:
        raise RuntimeError("file open failed")
    try:
        with nogil:
            for i in range(n):
                fprintf(fh, "%ld %ld %g\n", row[i], col[i], value[i])
    finally:
        fclose(fh)

时序:

原文:5.0 s 大熊猫:3.1秒 Cython:0.9秒