2016-04-22 5 views
0

私はPythonで折り畳まれたGibbsサンプラーを書き込もうとしていますが、私の行列の初期値を作成する際にメモリの問題が発生しています。私はむしろPythonの初心者です。以下は、私が説明していることの概要です。 6及びM:+ = 1から大きな行列を使用するとメモリエラーが発生する

  1. Tは、2のようないくつかの小さな数であり、T、ゼロのM行列(プラスアルファ値)を、作成:4で私は私の目標をすることである私のMemoryError

    を受け取ります

    import numpy as np 
    import pandas as pd 
    M = 500 
    N = 10000 
    T = 6 
    alpha = .3 
    NZM = np.zeros((T,M), dtype = np.float64) + alpha 
    
  2. 非常に大きくすることができ、次のようになりTトピックから多項分布によって生成された数字のM、Nの行列を作成します。

    Z = np.where(np.random.multinomial(1,[1./ntopics]*ntopics,size = M*N)==1)[1] 
    Z 
    
    array([[1, 3, 0, ..., 5, 3, 1], 
         [3, 5, 0, ..., 5, 1, 2], 
         [4, 5, 4, ..., 1, 3, 5], 
         ..., 
         [1, 2, 1, ..., 0, 3, 4], 
         [0, 5, 2, ..., 2, 5, 0], 
         [2, 3, 2, ..., 4, 1, 5]]) 
    
  3. 私はエラーが表示されるところ、このステップは.reshape(M*N)

    Z_index = Z.reshape(M*N) 
    
    array([1, 3, 0, ..., 4, 1, 5]) 
    
  4. を使用して、これらのうち、インデックスを作成します。私はZ_indexを使用して、Zの値として表示されるNZMの各行に1を追加します。ただし、オプション2は非常に低速で、オプション2はメモリエラーがあります。

    # Option 1 
    for m in xrange(M): 
        NZM[Z_index,m] += 1 
    
    # Option 2 
    NZM[Z_index,:] += 1 
    
    
    
    --------------------------------------------------------------------------- 
    MemoryError        Traceback (most recent call last) 
    <ipython-input-88-087ab1ede05d> in <module>() 
         2 # a memory error 
         3 
    ----> 4 NZM[Z_index,:] += 1 
    
    
    MemoryError: 
    

私は、この配列の行にそれがZ_indexに現れるたびに1を追加します。私が気付いていない、これを迅速かつ効率的に行う方法はありますか?これを読んでいただきありがとうございます。

+1

64ビットOSの場合は、仮想メモリを増やすことができます。さらに、numpyでHDFSを使用すると、ディスクへの連続した読み込み書き込みによってメモリに収まらないデータセットで動作するため、numpyでHDFSを使用することができます。 – Chris

+0

@Chris Pythonは利用可能なすべてのメモリを自動的に使用しませんか?私は32GBのメモリ(個人的なクリスマスの盛り上がり)を利用できますが、Pythonに何か事前に割り当てられた量以上を使用するように指示する必要がありますか? –

+1

IIRC 32ビットOSのPythonでは4GBのメモリしか使用できません。 – Greg

答えて

1

私の質問は質問hereと重複していますが、大きな重複インデックスに起因するエラーを探している人が一意であり、より簡単に見つけることができます。

シンプルな健全性チェックは、これが私が行っていると思っていたことをしていないことを示しています。私は、同じ行の倍数のインデックスが与えられていると、+ =はその行がインデックスに存在するたびにそれらの行に1つずつ追加すると仮定しました。

import numpy as np 
import pandas as pd 

NWZ = np.zeros((10,10), dtype=np.float64) + 1 

index = np.repeat([0,3], [1, 3], axis=0) 

index 

array([0, 3, 3, 3]) 

NWZ[index,:] += 1 

NWZ 

array([[ 2., 2., 2., 2., 2.], 
     [ 1., 1., 1., 1., 1.], 
     [ 1., 1., 1., 1., 1.], 
     [ 2., 2., 2., 2., 2.], 
     [ 1., 1., 1., 1., 1.]]) 

これは、同じ行の+ =複数のインスタンスは、それだけに追加1つを有する元の行につながる与えるようにそうではない見ることができます。操作「場所に」+=実行するので、私は、この操作は明示的に我々はそれがインデックスを反復処理として、さらには累積的に行われていないことがわかりしかし.__iadd__(1)を使用して

array([[ 2., 2., 2., 2., 2.], 
     [ 1., 1., 1., 1., 1.], 
     [ 1., 1., 1., 1., 1.], 
     [ 4., 4., 4., 4., 4.], 
     [ 1., 1., 1., 1., 1.]]) 

を返すことを想定しました。これにはない(と、ユーザはないはずアサート)が起こる理由として

直感的explenationため
NWZ[index,:].__iadd__(1) 

array([[ 2., 2., 2., 2., 2.], 
     [ 2., 2., 2., 2., 2.], 
     [ 2., 2., 2., 2., 2.], 
     [ 2., 2., 2., 2., 2.]]) 

あなたが行くことができhere

私の問題の別の解決方法は、最初に重複インデックスに行番号nが現れる回数の頻度表を作成することです。その後、私は追加をしているだけなので、それらの周波数を対応する行に追加します。

from scipy.stats import itemfreq 

index_counts = itemfreq(index) 

N = len(index_counts[:,1]) 
NWZ[index_counts[:,0].astype(int),:] += index_counts[:,1].reshape(N,1) 
NWZ 

array([[ 2., 2., 2., 2., 2.], 
     [ 1., 1., 1., 1., 1.], 
     [ 1., 1., 1., 1., 1.], 
     [ 4., 4., 4., 4., 4.], 
     [ 1., 1., 1., 1., 1.]]) 
関連する問題