私は不思議に思っています...たとえば、400MBのcsvファイルをpandasデータフレームに(read_csvまたはread_tableを使用して)読み取っている場合、これに必要なメモリ量を推測する方法はありますか?データフレームとメモリのより良い感覚を得ようとしています...
x=df.loc[[]]が0.1(ゼロ行を抽出するために)計算されるのに数秒かかり、さらに、元のデータフレームと同じように、おそらくその下のコピーのために数百メガバイトのメモリがかかることを発見しました。
私は不思議に思っています...たとえば、400MBのcsvファイルをpandasデータフレームに(read_csvまたはread_tableを使用して)読み取っている場合、これに必要なメモリ量を推測する方法はありますか?データフレームとメモリのより良い感覚を得ようとしています...
x=df.loc[[]]が0.1(ゼロ行を抽出するために)計算されるのに数秒かかり、さらに、元のデータフレームと同じように、おそらくその下のコピーのために数百メガバイトのメモリがかかることを発見しました。
回答:
df.memory_usage() 各列の占有量を返します。
>>> df.memory_usage()
Row_ID 20906600
Household_ID 20906600
Vehicle 20906600
Calendar_Year 20906600
Model_Year 20906600
...
インデックスを含めるには、を渡しindex=Trueます。
したがって、全体的なメモリ消費量を取得するには:
>>> df.memory_usage(index=True).sum()
731731000
また、渡すdeep=Trueことで、より正確なメモリ使用量レポートが有効になり、含まれているオブジェクトの完全な使用量が明らかになります。
これは、メモリ使用量には、配列のコンポーネントではない要素deep=False(デフォルトの場合)によって消費されるメモリが含まれないためです。
deep=True
deep=True
memory_usage()に、(予想どおり)メモリ使用量をバイト単位で返します。
これが異なる方法の比較です- sys.getsizeof(df)最も簡単です。
この例の場合、df814行、11列(2 int、9オブジェクト)のデータフレームです-427kbシェープファイルから読み取ります
>>>インポートシステム >>> sys.getsizeof(df) (結果をバイトで与える) 462456
>>> df.memory_usage() ... (各列を8バイト/行でリストします) >>> df.memory_usage()。sum() 71712 (おおよそ行*列* 8バイト) >>> df.memory_usage(deep = True) (各列の完全なメモリ使用量をリストします) >>> df.memory_usage(deep = True).sum() (結果をバイトで与える) 462432
データフレーム情報を標準出力に出力します。技術的にはこれらはキロバイトではなくキビバイト(KiB)です-docstringが言うように、「メモリ使用量は人間が読める単位(base-2表現)で表示されます。」したがって、バイトを取得するには1024を掛けます。たとえば、451.6 KiB = 462,438バイトです。
>>> df.info() ... メモリ使用量:70.0+ KB >>> df.info(memory_usage = 'deep') ... メモリ使用量:451.6 KB
g 上記のコードが参照するオブジェクトまたはモジュールは何ですか?
df.info(memory_usage="deep")していますが、「392.6 MB」を返しますがsys.getsizeof(df)、df.memory_usage(index=True, deep=True).sum()どちらも約「411718016」(〜411MB)を返します。3つの結果が一致しない理由を説明していただけますか?おかげで
df.memory_usage(deep=True).sum()ほぼ同じ結果を返しますdf.memory_usage(index=True, deep=True).sum()。私の場合、indexメモリはあまり必要ありません。興味深いことに、私はを見つけた411718016/1024/1024 = 392.6ので、 df.info(memory_usage="deep")を使用2^10してバイトをMBに変換する場合があり、混乱します。とにかくあなたの助けをありがとう:D。
df.infoメガバイト(10 ^ 6)ではなく、メビバイト(2 ^ 10)を返します-答えを修正します。
もう少しデータを議論に持っていきたいと思いました。
この問題について一連のテストを実行しました。
Python resourceパッケージを使用して、プロセスのメモリ使用量を取得しました。
そして、csvをStringIOバッファーに書き込むことで、そのサイズをバイト単位で簡単に測定できました。
私は2つの実験を実行し、それぞれが10,000行と1,000,000行の間でサイズが増加する20データフレームを作成しました。どちらも10列です。
最初の実験では、データセットで浮動小数点のみを使用しました。
これは、csvファイルと比較して、行数の関数としてメモリがどのように増加したかです。(メガバイト単位のサイズ)

2番目の実験でも同じアプローチをとりましたが、データセット内のデータは短い文字列のみで構成されていました。

csvのサイズとデータフレームのサイズの関係はかなり変化するようですが、メモリ内のサイズは常に2〜3倍大きくなります(この実験のフレームサイズの場合)。
私はより多くの実験でこの回答を完成させたいと思います。何か特別なことを試してもらいたい場合はコメントしてください。
これを逆に行う必要があります。
In [4]: DataFrame(randn(1000000,20)).to_csv('test.csv')
In [5]: !ls -ltr test.csv
-rw-rw-r-- 1 users 399508276 Aug 6 16:55 test.csv
技術的にはメモリはこれについてです(インデックスを含みます)
In [16]: df.values.nbytes + df.index.nbytes + df.columns.nbytes
Out[16]: 168000160
したがって、メモリが168MB、ファイルが400MB、100万行、20フロート列
DataFrame(randn(1000000,20)).to_hdf('test.h5','df')
!ls -ltr test.h5
-rw-rw-r-- 1 users 168073944 Aug 6 16:57 test.h5
バイナリHDF5ファイルとして書き込むと、はるかにコンパクト
In [12]: DataFrame(randn(1000000,20)).to_hdf('test.h5','df',complevel=9,complib='blosc')
In [13]: !ls -ltr test.h5
-rw-rw-r-- 1 users 154727012 Aug 6 16:58 test.h5
データはランダムだったので、圧縮はあまり役に立ちません
read_csvか?
nbytesたとえば、データフレームに文字列がある場合は、かなり過小評価されます。
dtype配列のsがわかっている場合は、データを保存するために必要なバイト数と、Pythonオブジェクト自体のバイト数を直接計算できます。numpy配列の有用な属性はですnbytes。あなたはパンダにアレイからのバイト数を取得することができますDataFrame実行して
nbytes = sum(block.values.nbytes for block in df.blocks.values())
objectdtype配列はオブジェクトごとに8バイトを格納します(オブジェクトdtype配列はopaqueへのポインターを格納しますPyObject)。したがって、csvに文字列がある場合、read_csvそれらを考慮に入れて、それらをobjectdtype配列に変換し、それに応じて計算を調整する必要があります。
編集:
の詳細については、numpyスカラー型のページをご覧くださいobject dtype。参照のみが保存されるため、配列内のオブジェクトのサイズも考慮する必要があります。そのページが言うように、オブジェクト配列はPython listオブジェクトにいくぶん似ています。
はいあります。パンダは、データをndarraydtypeでグループ化した2次元の複雑な構造に格納します。ndarray基本的には、小さなヘッダーを持つ生のCデータ配列です。したがって、そのサイズにdtype配列の次元を乗算するだけで、そのサイズを見積もることができます。
例:2行np.int32と5 np.float64列の1000行がある場合、DataFrameには2x1000 np.int32アレイが1つと5x1000 アレイが1つnp.float64あります。
4バイト* 2 * 1000 + 8バイト* 5 * 1000 = 48000バイト
DataFrame?
pandasがread_table、Cythonの非常に効率的な実装があり(numpyのloadtxtよりもはるかに優れています)、データを解析して直接に格納すると想定していndarrayます。
これにより、Pythonの任意のオブジェクトがメモリ内のサイズになります。内部はパンダとナンピーに関してチェックする必要があります
>>> import sys
#assuming the dataframe to be df
>>> sys.getsizeof(df)
59542497
topしてからShift + M、私のメモリ使用量をソートします。