Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/288.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 从文件中读取数字列表的最快方法_Python_Optimization - Fatal编程技术网

Python 从文件中读取数字列表的最快方法

Python 从文件中读取数字列表的最快方法,python,optimization,Python,Optimization,我在Stack Overflow中发现了一些类似的问题,但我相信我可以从针对我的案例的建议中获益 我必须将大约8万个实值数字列表存储在一个文件中,然后再重新读取 首先,我尝试了cPickle,但阅读时间并不吸引人: >>> stmt = """ with open('pickled-data.dat') as f: data = cPickle.load(f) """ >>> timeit.timeit(stmt, 'import cPickle',

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

我必须将大约8万个实值数字列表存储在一个文件中,然后再重新读取

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

>>> stmt = """
with open('pickled-data.dat') as f:
    data = cPickle.load(f)
"""
>>> timeit.timeit(stmt, 'import cPickle', number=1)
3.8195440769195557
然后我发现将数字存储为纯文本可以加快读取速度(这是有道理的,因为
cPickle
必须担心很多事情):

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


有什么想法吗?

如果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*4
更改为
nelem*8
。这里可能存在一些小的可移植性问题(例如数据类型的endianness和sizeof)

如果您存储了这么多列表,sqlite数据库不是更好的数据结构吗?您尝试过
csv
模块的阅读器了吗?这将避免手动
split
您调用的操作。@br如果数据库看起来像是一个滥杀滥伤,我只需要加载所有这些列表。@mutzmatron是的,它会自动进行拆分,但是比我的第二个版本要慢一点。我推荐mgilson的第二个答案-如果数据允许,使用
numpy
fromfile
-这可能是最快的选择之一。我怀疑numpy fromfile相对优化,可能是比struct更好的解决方案,情况允许的话,@mutzmatron——是的,可能吧——不过实际上应该不会有太大的区别。我敢打赌,它们做的事情几乎是一样的——numpy的优点是它可以将对象放入顺序内存中(基本上只需要分配一个块和一个指针来执行指针算术)。另一方面,struct可能仍然只分配一个块,但它还需要为读取的每个浮点值分配一个指针,所以这是一点额外的工作。无论哪种方式,我都希望它比读取ascii文本、将其转换为浮点(都在非类型化python框架内完成)更快。谢谢,
numpy.fromfile
大约花费了0.02秒。@mgilson-我建议您编辑您的答案,以反映
numpy.fromfile
是选择的答案-可能建议首先建议
numpy.fromfile
并添加
结构作为替代方案
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) ]