1

複雑な種類のdictを使用して、いくつかのキーの値を動的に変更する必要があります。それで私はそれを次の方法で試しましたが、約32GBのRAMを備えたMemoryErrorに遭遇しました。sys.getsizeof(d)は393356を返し、sys.getsizeof(d.items())は50336です。Pythondictを間違った方法で使用しましたか?誰か助けてくれませんか!?

d=nltk.defaultdict(lambda:nltk.defaultdict(float))
for myarticlewords in mywords:
    for i in myarticlewords:
        for j in myarticlewords:
            d[i][j]+=1.0   

トレースバックは「d[i][j] +=1.0」で停止しました

私が試したとき:

dd=dict( (i,d[i].items() ) for i in d.keys() )

Traceback (most recent call last):
    File "<pyshell#34>", line 1, in <module>
    dd=dict( (i,d[i].items() ) for i in d.keys() )
   File "<pyshell#34>", line 1, in <genexpr>
   dd=dict( (i,d[i].items() ) for i in d.keys() )
MemoryError

ありがとう!

4

1 に答える 1

3

32 ビット版の Python を使用しているようです。Windows を実行している場合、おそらく32 ビット プログラムのWindows メモリ制限(2 GB) に達しています。

これは、私がいくつかの経験に基づいた推測に基づいて計算した数値と一致しています。まず、いくつかの重要な事実: dict 自体getsizeofのサイズのみを返し、そこに格納されているものは返しません。これは、すべての「コンテナ」タイプに当てはまります。また、非常に多くの項目が追加されるたびに、辞書のサイズがずらっと大きくなります。

ここで、約 5500 から 21000 項目の辞書を保存するとgetsizeof786712つまり393356 * 2. 私のバージョンの Python は 64 ビットなので、32 ビット バージョンの Python を使用して 5500 から 21000 のアイテムを保存していることを強く示唆しています。を使用しnltkています。これは、単語ダイグラムをここに保存していることを示唆しています。つまり、最低でも約 5500 語が必要です。これらの単語ごとに 2 つ目の辞書を保存していますが、これも 5500 項目の辞書です。したがって、ここに実際にあるのは、バイト数に加えて、ワードストレージ用393356 + 393356 * 5500の最小バイト数です。5500 * 20すべてを要約すると:

>>> (393356 + 393356 * 5500 + 5500 * 20) / 1000000000.0
2.163961356

少なくとも 2GB のデータを保存しようとしています。つまり、この 32 ギガバイトのメモリを利用したい場合は、64 ビット バージョンの Python にアップグレードする必要があります。


パフォーマンスが気になる場合は、辞書を保存するのではなく、pickle(または) を使用することをお勧めします。を設定しても、おそらく遅くなります。cPickleshelveshelvewriteback=True

>>> shelve_d = shelve.open('data', writeback=True)
>>> normal_d = {}
>>> def fill(d):
...    for i in xrange(100000):
...        d[str(i)] = i
...        
>>> %timeit fill(shelve_d)
1 loops, best of 3: 2.6 s per loop
>>> %timeit fill(normal_d)
10 loops, best of 3: 35.4 ms per loop

で辞書を保存するのpickleにももちろん時間がかかりますが、少なくとも計算自体が遅くなることはありません。

于 2012-08-09T13:14:03.700 に答える