1

私は非常に大きな配列を作成しています。この配列をメモリに保存するのではなく、ファイルに書き込めるようにしたいと思います。これは、後でインポートできる形式である必要があります。

私はピクルスを使用しますが、ピクルスは完成したファイル構造に使用されているようです。

次の例では、out変数をメモリに保存されたオブジェクトではなくファイルにする方法が必要です。

out = []
for x in y:
    z = []
    #get lots of data into z
    out.append(z)
4

3 に答える 3

2

ストリーミングピクルスを見てください。

Streaming-pickleを使用すると、Pythonデータ構造のシーケンスをストリーミング(インクリメンタル)方式でディスクとの間で保存/ロードできるため、通常のpickleよりもはるかに少ないメモリを使用できます。

実際には、3つの短いメソッドを持つ単一のファイルです。例を含むスニペットを追加しました:

try:
    from cPickle import dumps, loads
except ImportError:
    from pickle import dumps, loads


def s_dump(iterable_to_pickle, file_obj):
    """ dump contents of an iterable iterable_to_pickle to file_obj, a file
    opened in write mode """
    for elt in iterable_to_pickle:
        s_dump_elt(elt, file_obj)

def s_dump_elt(elt_to_pickle, file_obj):
    """ dumps one element to file_obj, a file opened in write mode """
    pickled_elt_str = dumps(elt_to_pickle)
    file_obj.write(pickled_elt_str)
    # record separator is a blank line
    # (since pickled_elt_str might contain its own newlines)
    file_obj.write('\n\n')

def s_load(file_obj):
    """ load contents from file_obj, returning a generator that yields one
        element at a time """
    cur_elt = []
    for line in file_obj:
        cur_elt.append(line)

        if line == '\n':
            pickled_elt_str = ''.join(cur_elt)
            elt = loads(pickled_elt_str)
            cur_elt = []
            yield elt

使用方法は次のとおりです。

from __future__ import print_function
import os
import sys

if __name__ == '__main__':
    if os.path.exists('obj.serialized'):
        # load a file 'obj.serialized' from disk and 
        # spool through iterable      
        with open('obj.serialized', 'r') as handle:
            _generator = s_load(handle)
            for element in _generator:
                print(element)
    else:
        # or create it first, otherwise
        with open('obj.serialized', 'w') as handle:
            for i in xrange(100000):
                s_dump_elt({'i' : i}, handle)
于 2012-12-12T14:52:30.017 に答える
1

HDF5多分?かなり幅広いサポートがあり、既存のデータセットに追加できます。

于 2012-12-12T15:00:17.993 に答える
0

長さインジケーターを前に付けてストリングピクルスを使用することを想像できます。

import os
import struct
import pickle # or cPickle

def loader(inf):
    while True:
        s = inf.read(4)
        if not s: return
        length, = struct.unpack(">L", s)
        data = inf.read(length)
        yield pickle.loads(data)

if __name__ == '__main__':
    if os.path.exists('dumptest'):
        # load file
        with open('dumptest', 'rb') as inf:
            for element in loader(inf):
                print element
    else:
        # or create it first, otherwise
        with open('dumptest', 'wb') as outf:
            for i in xrange(100000):
                dump = pickle.dumps({'i' : i}, protocol=-1) # or whatever you want as protocol...
                lenstr = struct.pack(">L", len(dump))
                outf.write(lenstr + dump)

これにより、実際に必要な時間より長くデータがキャッシュされることはなく、アイテムが相互に分離され、さらにすべてのピクルスプロトコルと互換性があります。

于 2012-12-12T15:27:08.047 に答える