私は1M行のメモリプロファイリングを行いました。勝利した構造は、すべての数値インデックスに対してarray.arrayを使用し、文字列(147MBのデータと310MBのパンダへの変換)のリストを使用することです。
は、Pythonのマニュアルによると
配列は、シーケンス型であり、それらに格納されているオブジェクトの種類が制約されること を除き、非常に多くのリストのように振る舞います。
これらのメソッドにも追加メソッドがあり、非常に高速の追加速度を持つ可能性があります。
2位は2つの別々のリストになります。 (308MBと450MB)
dictを使用し、タプルが4つのリストを使用する他の2つのオプションは、最悪でした。 Dict:339MB、524MB。 4つのリスト:308MB、514MB。
ここでは配列の使用方法を示します。配列:4のタプルの
一覧::ここで
In [1]: from array import array
In [2]: import gc
In [3]: import pandas as pd
In [4]: %load_ext memory_profiler
In [5]: a1=array("l",range(1000000))
In [6]: a2=array("l",range(1000000))
In [7]: a3=array("l",range(1000000))
In [8]: b=[str(x*111) for x in list(range(1000000))]
In [9]: gc.collect()
Out[9]: 0
In [10]: %memit a1,a2,a3,b
peak memory: 147.64 MiB, increment: 0.32 MiB
In [11]: %memit dfpair=pd.DataFrame(b, index=pd.MultiIndex.from_arrays([a1,a2,a3], names=['a','b','c']))
peak memory: 310.60 MiB, increment: 162.91 MiB
は、(非常に長い)コードの残りの部分である
In [1]: import gc
In [2]: import pandas as pd
In [3]: %load_ext memory_profiler
In [4]: a=list(zip(list(range(1000000)),list(range(1000000)),list(range(1000000))))
In [5]: b=[str(x*111) for x in list(range(1000000))]
In [6]: d2=[x+(b[i],) for i,x in enumerate(a)]
In [7]: del a
In [8]: del b
In [9]: gc.collect()
Out[9]: 0
In [10]: %memit d2
peak memory: 308.40 MiB, increment: 0.28 MiB
In [11]: %memit df = pd.DataFrame(d2, columns=['a','b','c','d']).set_index(['a','b','c'])
peak memory: 514.21 MiB, increment: 205.80 MiB
辞書:
In [1]: import gc
In [2]: import pandas as pd
In [3]: %load_ext memory_profiler
In [4]: a=list(zip(list(range(1000000)),list(range(1000000)),list(range(1000000))))
In [5]: b=[str(x*111) for x in list(range(1000000))]
In [6]: d = dict(zip(a, b))
In [7]: del a
In [8]: del b
In [9]: gc.collect()
Out[9]: 0
In [10]: %memit d
peak memory: 339.14 MiB, increment: 0.23 MiB
In [11]: %memit dfdict=pd.DataFrame(list(d.values()), index=pd.MultiIndex.from_tuples(d.keys(), names=['a','b','c']))
peak memory: 524.10 MiB, increment: 184.95 MiB
2個のアレイ:
In [1]: import gc
In [2]: import pandas as pd
In [3]: %load_ext memory_profiler
In [4]: a=list(zip(list(range(1000000)),list(range(1000000)),list(range(1000000))))
In [5]: b=[str(x*111) for x in list(range(1000000))]
In [6]: gc.collect()
Out[6]: 0
In [7]: %memit a,b
peak memory: 307.75 MiB, increment: 0.19 MiB
In [8]: %memit dfpair=pd.DataFrame(b, index=pd.MultiIndex.from_tuples(a, names=['a','b','c']))
peak memory: 459.94 MiB, increment: 152.19 MiB
ここで
代わりにnumpy配列を使用してみませんか?彼らはリストと辞書の両方よりもはるかに少ないメモリフットプリントを持っています –
私はデータのサイズがわからないのでnumpyを使用していないので、リストや辞書を作成してからnumpy配列やpandas Dataframeを初期化しなければなりません。 – snowleopard
リストのメモリ使用量のベンチマークを書くでしょう –