numpy配列のPythonメモリ使用量


156

pythonを使用していくつかの大きなファイルを分析していて、メモリの問題が発生しているため、sys.getsizeof()を使用して使用状況を追跡してきましたが、配列の数が多い場合の動作は奇妙です。これは、私が開かなければならないアルベドのマップを含む例です:

>>> import numpy as np
>>> import struct
>>> from sys import getsizeof
>>> f = open('Albedo_map.assoc', 'rb')
>>> getsizeof(f)
144
>>> albedo = struct.unpack('%df' % (7200*3600), f.read(7200*3600*4))
>>> getsizeof(albedo)
207360056
>>> albedo = np.array(albedo).reshape(3600,7200)
>>> getsizeof(albedo)
80

データはまだ残っていますが、オブジェクトのサイズである3600x7200ピクセルマップは、約200 MBから80バイトになりました。私の記憶の問題が終わってすべてを単純な配列に変換することを願っていますが、この動作は、trueの場合、情報理論や熱力学などの法則に何らかの形で違反すると思います。 getsizeof()がnumpy配列では機能しないと信じる傾向があります。何か案は?


8
上のドキュメントからsys.getsizeof:「オブジェクトのサイズをバイト単位で返します。オブジェクトは任意のタイプのオブジェクトにすることができます。すべての組み込みオブジェクトは正しい結果を返しますが、これはサードパーティの拡張機能に当てはまる必要はありません。実装固有。対象となるオブジェクトのメモリ消費ではなく、オブジェクトに直接起因するメモリ消費のみが考慮されます。」
Joel Cornett 2012

1
これによりgetsizeof特にサードパーティの拡張機能では、メモリ消費の信頼性の低い指標になります。
Joel Cornett、2012

13
基本的に、ここでの問題は、新しい配列ではなくをresize返すことですview。実際のデータではなく、ビューのサイズを取得しています。
mgilson 2012

そのためsys.getsizeof(albedo.base)、非表示のサイズを与えます。
エリック

回答:


236

array.nbytesnumpy配列に使用できます。次に例を示します。

>>> import numpy as np
>>> from sys import getsizeof
>>> a = [0] * 1024
>>> b = np.array(a)
>>> getsizeof(a)
8264
>>> b.nbytes
8192

import sysを実行した後のsys.getsizeof(a)。
エディ

2
b.__sizeof__()に相当sys.getsizeof(b)
パラッシュ

1
round(getsizeof(a) / 1024 / 1024,2)MBを取得するには
gies0r

13

フィールドnbytesは、配列のすべての要素のサイズをバイト単位で示しますnumpy.array

size_in_bytes = my_numpy_array.nbytes

これは「配列オブジェクトの非要素属性」を測定しないため、実際のサイズ(バイト)はこれよりも数バイト大きくなる可能性があることに注意してください。


この答えはまだ配列を作成するので、「リストから配列に変換する必要がない」という意味だと思います。GWWの答えが最初にリストを作成し、それを配列に変換することは事実ですが、OPはすでに配列を持っているので、それは要点の横にあります...ポイントは、数の多い配列のサイズを取得する方法であり、それはそうではありませんそもそもアレイをどのように取得したかが重要です。既存の配列を再形成すると言っても、同様にこの答えを批判できます。
Moot

@Mootこんにちは、コメントをありがとう。問題は、配列のバイト単位のサイズを取得する方法についてです。私のスニペットが最初に配列を作成することは事実ですが、これは実行可能な完全な例を提供することのみを目的としています。私はこれを強調するために私の答えを編集します。
El Marce、

1

Pythonノートブックでは、「ぶら下がり」numpy.ndarray、特に、などに格納されていて_1_2実際に存続することを決して意図されていないものを除外したいことがよくあります。

私はこのコードを使用して、それらすべてとそのサイズのリストを取得します。

ここかどうlocals()globals()はわかりません。

import sys
import numpy
from humanize import naturalsize

for size, name in sorted(
    (value.nbytes, name)
    for name, value in locals().items()
    if isinstance(value, numpy.ndarray)):
  print("{:>30}: {:>8}".format(name, naturalsize(size)))
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.