2016-12-15 17 views
2

2D配列のリストを3D配列にキャストしようとしていますが、データがコピーされているかどうかを知りたいと思います。このプログラムで例えば 2D numpy配列のリストを3D配列にキャストするときのメモリコピー

、:

images = [] 
for i in range(10): 
    images.append(numpy.random.rand(100, 100)) 
volume = numpy.array(images) 

images[n]と同じメモリブロックを参照しているvolume[n]かどうかを確認する方法はありますか?

データを3D配列にする必要があります。画像のリストを入力として受け入れるべきか、データがコピーされるかどうかを評価しようとしています。私は非常に大きなデータセットを扱っているので、データコピーは受け入れられません。

答えて

1

numpyをインポートした後、Windowsタスクマネージャーは私のPythonプロセスで14 MBを使用していると言いました。 images(ただし、range(5000))のビルド後、396 MB(382 MB以上)になりました。 volumeをビルドした後、それは778 MB(さらに382 MB)でした。それはコピーのように見えます。 numpy.arrayからのWindows 10上でのPython 3.5.2で

0

をnumpyの1.11.1を使用する:

コピー:BOOLオプション

をtrue(デフォルト)場合は、そのオブジェクトがされコピーされます。それ以外の場合は、__array__がコピーを返す場合にのみコピーが行われ、objがネストされたシーケンスの場合は、その他の要件(dtype、orderなど)を満たすにはコピーが必要な場合のみコピーが行われます。

copy=Falseでテストした後、ネストしたシーケンスがあることは確かです。残念ながら__array__がリスト(または他のイテレータ)のコピーを返すかどうかを判断するのは私のgoogle-fuを超えていますが、おそらくnumpyの配列を繰り返すことはできません。

2

私はリストと配列の間でストレージの違いについての質問を参照することもできますが、あなたの場合、それを調整する:

あなたのリストは、メモリ内に他の場所に格納された配列オブジェクトへのポインタとデータバッファを持っています。 images.appendはそのポインタリストを更新するだけです。リストコピーはポインタをコピーするだけです。

アレイは、すべてのデータを連続したメモリバッファに格納します。したがって、volumeを作成するnp.array()は、各コンポーネント配列から独自のバッファに値をコピーする必要があります。 np.concatenateのバージョンを使用して3d配列をコンパイルする場合も同様です。

numpy多くの場合、機能は開始時にx=np.asarray(x)ステートメントを持つことがよくあります。実際には、「私は配列で作業していますが、私はあなたに私にリストを教えさせます」と言っています。

これをスキップして、3D配列のみを受け入れることができます。しかし、その3dアレイはどのように構築されましたか?ランダム3D配列のためには、1文ですることによって取得することができます。

arr = numpy.random.rand(10, 100, 100) 

が、画像が個別ファイルからロードされている場合は、何かまたは誰かが画像の3D配列を作成するために、1つまたは複数のコピーを実行する必要があります。あなたかあなたのユーザーですか?

私の一般的なアドバイスは、あなたのコードが実行され、あなたが知っている限り、コピーが高価であることを知っているか、MemoryErrorの問題にぶつかり始めるまで、

+0

ありがとうございました。これは、numpy配列が必然的にメモリ連続でなければならない場合や、トップレベルのインデックスが互いに連続していないサブ配列を参照できる場合、私が本当に求めていたことです。 – PiRK

+0

あなたの質問について:私はジェネリックウィジェットを使って複数の画像をブラウズしています。画像はユーザーによって提供されなければならないので、入力データの仕様について厳密にする必要があるのか​​、ユーザーの生活をより簡単にするのかについて少し不明です。私は、一部のユーザーが2D配列のリストとしてデータをロードできるように要求するか、または悪いことにリストのリストのリストをロードできるようにすることを心配しています。私のウィジェットが最初にソートするのに高価だったデータをすべて並べ替えるのに時間がかかると、同じユーザーが文句を言うでしょう。 – PiRK

+0

私のウィジェットは、3つの可能な方向のどれかに直角にボリュームをスライスするために、データを転置することができる必要があります。そのため、ビューを使用するためには、データを細かい配列にする必要があります。 また、多次元リスト(「https://github.com/PiRK/silx/blob/ImageStack/silx/utils/array_like.py#L211」)よりも「転置」しやすいh5pyデータセットを受け入れる予定です。 私はユーザーがシンクロトロン/ X線イメージング技術に取り組んでいる科学者であるため、数ギガバイト(おそらく数百ギガバイト)のデータサイズが必要です。 – PiRK

1

numpyあなたは(のためのまともな代理であるが、この場合にはコピーされなかった)2つの配列を共有メモリ

for i, img in enumerate(images): 
    print(i, numpy.may_share_memory(img, volume)) 
# all False 

かどうかをテストすることができます彼らは、この時間をコピーされたように見えます。

+0

非常に便利な機能です、ありがとうございます。 – PiRK

関連する問題