2016-08-19 6 views
2

私は巨大な(16 GB)Pythonリストを持っていて、それをnumpy配列のインプレースに変換したいのです。私はそれがコピーだせずにnumpy arrayにこのhuge_listを変換するためのいくつかの効率的な方法を探していますPythonリストをNumpy配列のInPlaceに変換する

huge_array = np.array(huge_list).astype(np.float16) 

この文は余裕がありません。

誰でも効率的な方法を提案できますか?それはまずリストをディスクに保存してからnumpy配列としてロードすることですが、私はそれで大丈夫です。

大変ありがとうございます。

EDIT 1:huge_listは実行時に作成されるメモリ内のpythonリストで、既に16GBを使用しています。私はそれをnumpy float16配列に変換する必要があります。

+0

あなたはnp.saveとnp.loadを除外していますか? –

+0

'np.array'メソッドが時間がかかりすぎるのか、それともメモリエラーが発生しますか? – hpaulj

+0

私はスピードではなく、忘れられないことを心配しています。したがって、np.arrayはメモリエラーを発生させる可能性があります。 @DanPatterson huge_listはまだディスク上にありません。実行時に生成されるメモリ内にあるので、numpy float16配列に変換する必要があります。 – Ahmed

答えて

2

np.array(huge_list, dtype=np.float16)でご利用いただけますが、一度ではなく、それ以降のコピーのみリスト、高速になります二回


あなたはおそらくコピーであるため、このコピーを作成することを心配する必要はありません

オリジナルより小さいたくさん:

>>> x = [float(i) for i in range(10000)] 
>>> sys.getsizeof(x) 
83112 
>>> y = np.array(x, dtype=np.float16) 
>>> sys.getsizeof(y) 
20096 

しかし、それはそれの最悪ではありません - Pythonのリストで、リスト内のそれぞれの数は、そののメモリを取っています自分自身:

したがって、numpy配列は〜15x小さいです!

+0

ここではメモリが優先され、スピードは副次的な問題です。 – Ahmed

+0

これは 'hugep.array(huge_list).view(np.float16)'の1/5のメモリも使用しています。 'huge_list'には浮動小数点が含まれていると仮定して – Eric

+0

それを指摘してくれてありがとう、私のマシンは32GBのメモリを搭載しています。リストのサイズは16GB(float16)です。別の16GBコピーを作成してメモリをオーバーフローさせたくありません。 – Ahmed

2

前述したように、最も簡単なのは、配列をファイルにダンプし、そのファイルをnumpy配列としてロードすることです。

まず我々は、巨大なリストのサイズが必要です。このすべてが同じ環境で発生した場合、我々はメモリをクリアすることを確認し、我々は、ディスク

dumpfile = open('huge_array.txt', 'w') 

for item in huge_list: 
    dumpfile.write(str(item)+"\n") 
dumpfile.close() 

にそれをダンプし

huge_list_size = len(huge_list) 

次の

del huge_list 

次に、簡単なリードジェネレータを定義します。

def read_file_generator(filename): 
    with open(filename) as infile: 
     for i, line in enumerate(infile): 
      yield [i, line] 

そして、我々は、我々はちょうど私の前の回答が間違っていた

huge_array = np.zeros(huge_list_size, dtype='float16') 

for i, item in read_file_generator('huge_array.txt'): 
    huge_array[i] = item 

を作成した発電機で埋めるゼロのnumpyの配列を作成します。私はあなたが複数の方法でこれを行うことができ、それはのようにhpaulj

でコメントされていないソリューションを、使用するには、以下の提案、最も簡単にはちょうど ファイルへの配列をダンプしてから、そのファイルをロードすることですnumpyの配列として:

dumpfile = open('huge_array.txt', 'w') 

for item in huge_array: 
    print>>dumpfile, item 

その後も、あなたは、このデータにさらに計算を実行したい場合はすることができますnumpyの配列

huge_array = numpy.loadtxt('huge_array.txt') 

としてそれをロード はmemmapのためにjoblibライブラリを使用しています。これは、大量の配列のcmputationsを扱うのに、 で非常に便利です。 https://pypi.python.org/pypi/joblib

+2

しかし、 'loadtxt'は値をリストにロードし、ロードされたら' np.array(alist) 'を実行します。 – hpaulj

+0

numpy 1.10.4のnp.loadtxtのソースを確認しました。 メソッドloadtxtのnpyioの808行目では、実際にリストが指定され、直後に読み込まれます。行936で、リストは 'np.array(X、dtype)'コールを介してnumpy配列に変換されます。 ありがとう、私はそれを知らなかった。私は自分の答えをできるだけ早く調整する – Laurens

+0

約束どおりの答えを更新しました。私はhpauljに同意する必要があります。チャンクはよりよい解決策かもしれませんが、それはデータの生成中に行われなければならず、質問に答えなかったでしょう。 – Laurens

0

あなたはnumpysaveload機能を使用することができます。

あなたがnumpyの配列に直接ロードされますnp.savenp.loadに引数として通常のPythonリストを使用することができます。

例:

from tempfile import TemporaryFile 
outfile = TemporaryFile() 
x = [1, 2, 3] 
np.save(outfile, x) 

outfile.seek(0) 
np.load(outfile) 
関連する問題