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 バイトの float として格納するだけで十分であると想定しています。実数の倍精度数が必要な場合は、フォーマット ステートメントを f から d に変更nelem*4し、 に変更しnelem*8ます。ここには、いくつかの小さな移植性の問題がある可能性があります (エンディアンとデータ型のサイズなど)。

于 2012-08-02T14:32:43.310 に答える