2012-01-26 6 views
1

私はpythonの初心者です。私は次のコードを実行しており、python2.7でメモリエラーが発生しています。 私はopencvを使用しているので、私はpython2.7で作業しています。私は前の記事を読んだが、私はそれらから多くを理解していない。大規模な複雑さのためにPython 2.7のメモリエラー

s={} 
ns={} 
ts={} 
for i in range(0,256): #for red component 
    for j in range(0,256): #for green component 
     for k in range(0,256): # for blue component 
      s[(i,j,k)]=0 
      ns[(i,j,k)]=0 
      ts[(i,j,k)]=i*j*k 

助けてください。コードは、赤、緑、青の成分の周波数を保存しようとします。そして、私はこれらの値を0に初期化しています。

+1

1)約3 * 300^3のオブジェクトを作成しています。 2)あなたの意図は不明です。なぜあなたはこれをしたいのですか? 3)あなたはあなたの記憶限界を知らせません。チェックしないとコードが* 4GBを超えます(それより高くなると感じます)が、それ以外ではそれ以外のものは派生できません。 – Makoto

+3

さて、それはたくさんのメモリを割り当てようとしています。そのためです。おそらく、達成しようとしていることを教えて、質問を更新するべきでしょう。誰かがあなたの問題を解決するために別の方法を考え出すかもしれません。 –

+0

私はピクセルの赤、青、緑の成分のfrequnecyを保存しようとしています。 –

答えて

5

問題1:ループのたびにすべてのrangeリストを構築する代わりに、itertoolsを使用してください。 xrangerangeのようなイテレータオブジェクトを返し、productは指定されたイテラブルから要素のタプルを選択するイテレータを返します。

事実2:大きなデータの場合はnumpyを使用してください。このようなことのために設計されたマトリックス実装です。

>>> import numpy as np 
>>> from itertools import product 
>>> x=np.zeros((256,256,256)) 
>>> for i, j, k in product(xrange(256), repeat=3): 
...  x[i,j,k]= i*j*k 
... 

私には約5秒、予想されるメモリ量がかかります。

$ cat /proc/27240/status 
Name: python 
State: S (sleeping) 
... 
VmPeak: 420808 kB 
VmSize: 289732 kB 

あなたは3つの256 * 256 * 256の配列を割り当てようとした場合、それぞれが約17 100万エントリを持っているので、あなたが実際に、システム全体のメモリ制限に遭遇することがあります。幸いにもnumpyは、配列をディスクに永続化させます。

あなたはPIL (Python Imaging Library)に出会ったことがありますか?それが役に立つかもしれません。

+0

ありがとうございました... –

+0

@JannatArora言い訳がありませんでした。整数配列(よりメモリ効率が良い)が必要な場合は、 'x = np.zeros((...)、dtype = int)' 。 – katrielalex

+0

ありがとうございました...これも –

0

すべての変数が1バイトを使用していても、そのプログラムには405 MBのRAMが必要です。

限られたスペースに多くを格納するには、圧縮を使用する必要があります。

編集:Pythonでヒストグラムを作成する場合は、see this nice example of using the Python Image Library (PIL)です。ハードワークは、これらの3線で行われます。実際のところ

import Image 
img = Image.open(imagepath) 
hist = img.histogram() 
+0

コードは、画像のピクセルの赤、緑、青の成分の頻度を保存しようとします。私はPythonに慣れていないので、圧縮技術を提案してください。 –

+0

デルタエンコーディングはオフセットと相違点のみを格納します。画像データを保存したいので、PILのような効率的なエンコーディングライブラリが既に存在します。 JPEGではなく、PNGやTIFFのような可逆フォーマットを使用してください。 –

1

、あなたのプログラムがdictsの値データのため、少なくとも300 * 300 * 300 * 4 * 3バイトのみ必要(!) 。また、キータプルは300 * 300 * 300 * 3 * 3 * 4バイトを占めます。

合計1296000000バイト、つまり1.2 GiBのデータです。

この計算には、dict内のデータを維持するオーバーヘッドは含まれません。

したがって、マシンに障害が発生した場合のメモリ量によって異なります。

あなたは最初のステップを行うと、以前のように半分しかメモリを占有します(理論的に)どの

s = {} 
ns = {} 
ts = {} 
for i in range(0, 300): 
    for j in range(0, 300): 
     for k in range(0, 300): 
      index=(i, j, k) 
      s[index]=j 
      ns[index]=k 
      ts[index]=i*j*k 

を行うことができます - だけでなく、データのみのために、インデックスタプルが再利用されます。


あなたの説明(単なるカウントしたいもの)から、事前に初期化するための完全な範囲の組み合わせは必要ありません。したがって、質問に示されている初期化を省略し、実際にデータがある場所にのみこれらの値を格納するストレージを構築することができます。

defaultdict()を使用するか、手動でその動作を模倣することができます。ほとんどの組み合わせがカラー「パレット」で使用されていないと思われます。

from collections import defaultdict 
make0 = lambda: 0 
s = defaultdict(make0) 
ns = defaultdict(make0) 
# what is ts? do you need it? 

ここでは、必要に応じて書き込み可能な3つのdictオブジェクトがあります。次に、あなたが実際に持っている色の組み合わせごとに、s[index] += 1 respを実行することができます。 ns[index] += 1

私はあなたのtsについてよくわかりません - あなたはそれを計算することができますか、別の解決策を見つける必要があります。

+0

ありがとうございました...しかし、それでも私のプログラムではメモリエラーが発生しています。 –

+0

もちろんそれは与える。あまりにも多くのメモリを必要とするすべてのプログラムは 'MemoryError'を与えます。必要なメモリ量を減らそうとする必要があります。私はそのための道を示すために私の質問を編集しました。 – glglgl

+0

あなたのアプローチはありがたいです...しかし、私は受け入れられた答えとして設定することができません...ごめんなさい –

関連する問題