1

我在 Stack Overflow 中发现了一些类似的问题,但我相信我可以从针对我的案例的特定建议中受益。

我必须将大约 80,000 个实数值列表存储在一个文件中,然后再将它们读回。

首先,我尝试cPickle了,但阅读时间并不吸引人:

>>> stmt = """
with open('pickled-data.dat') as f:
    data = cPickle.load(f)
"""
>>> timeit.timeit(stmt, 'import cPickle', number=1)
3.8195440769195557

然后我发现将数字存储为纯文本可以更快地阅读(有道理,因为cPickle必须担心很多事情):

>>> stmt = """
data = []
with open('text-data.dat') as f:
    for line in f:
        data.append([float(x) for x in line.split()])
"""
>>> timeit.timeit(stmt, number=1)
1.712096929550171

这是一个很好的改进,但我认为我仍然可以以某种方式对其进行优化,因为用其他语言编写的程序可以更快地从文件中读取类似的数据。

有任何想法吗?

4

1 回答 1

2

如果 numpy 数组可行,numpy.fromfile可能是读取文件的最快选择(这是我几天前问的一个有点相关的问题)

或者,看起来你可以做得更好一点struct,虽然我还没有测试过:

import struct
def write_data(f,data):
    f.write(struct.pack('i',len()))
    for lst in data:
        f.write(struct.pack('i%df'%len(lst),len(lst),*lst))

def read_data(f):
    def read_record(f):
        nelem = struct.unpack('i',f.read(4))[0]
        return list(struct.unpack('%df'%nelem,f.read(nelem*4))) #if tuples are Ok, remove the `list`.

    nrec = struct.unpack('i',f.read(4))[0]
    return [ read_record(f) for i in range(nrec) ]

这假设将数据存储为 4 字节浮点数就足够了。如果您想要一个真正的双精度数,请将格式语句从 f 更改为 d 并更改nelem*4nelem*8. 这里可能存在一些小的可移植性问题(例如数据类型的字节序和大小)。

于 2012-08-02T14:32:43.310 回答