3

私は次の辞書構造を持っています(リストのリストによって形成される値を持つ10,000個のキー)

my_dic ={0: [[1,.65,3, 0, 5.5], [[4, .55, 3, 0, 5.5] ...(10,000th value)[3,.15, 2, 1,   2.5]], 
1:[[1,.65,3, 0, 5.5], [[4, .55, 3, 0, 5.5] ...(10,000th value)[3,.15, 2, 1, 2.5]] .....   
10,000th key:[[1,.65,3, 0, 5.5], [[4, .55, 3, 0, 5.5] ...(10,000th value)[3,.15, 2, 1, 2.5]]}

(注:データはダミーなので、キー全体で繰り返しました)

小さい要素リストで必要な論理データ型は次のとおりです。

inner_list = [int, float, small_int, boolean( 0 or 1), float]

Asys.getsizeof(inner_list)は、サイズが56バイトであることを示しています。12int キーにバイトを追加すると、68バイトになります。今、私は10^8そのようなリスト(10000 * 10000)を持っているので、メモリへの保存が大きな問題になりつつあります。メモリ内のデータが必要です(現時点ではDBはありません)。それを保存する最も最適化された方法は何ですか?何か関係があるに違いないと思う傾向がありますがnumpy、何が最善の方法であり、それをどのように実装するかについてはわかりません。助言がありますか ?

2)また、これらの辞書をメモリに保存しているので、使い終わったらすぐにそれらが占有しているメモリをクリアしたいと思います。Pythonでこれを行う方法はありますか?

4

1 に答える 1

2

1 つの考えとしては、辞書構造をより単純な構造に分割することですが、これは処理の効率に影響を与える可能性があります。

1キー用に別の配列を作成する

keys = array('i', [key1, key2, ..., key10000])

キーの可能な値に応じて、配列の特定の int 型をさらに指定できます。また、キー テーブルでバイナリ検索を実行できるように、キーを順序付けする必要があります。このようにして、Python 辞書の実装で使用されるハッシュ テーブルのスペースも節約できます。欠点は、O(logn)代わりにキー検索に時間がかかることですO(1)

2 inner_list 要素を 10000x10000 の行列または 100000000 の長さのリストに格納します

0 から 9999 までの各位置iはキー配列から取得できる特定のキーに対応するため、リストの各リストをi行列の ' 番目の行に配置し、各inner_list要素をその行の列に配置できます。

他のオプションは、それらを長いリストに入れ、キーの位置を使用してインデックスを作成するiことです。

idx = i*10000 + j

ここiで、 はキー配列内のキーjのインデックスであり、特定のinner_listインスタンスのインデックスです。

さらに、要素ごとに、inner_list合計 5 つの個別の配列を持つことができます。これにより、メモリ内のデータの局所性が多少損なわれます。

int_array = array('i', [value1, ..., value100000000])
float1_array = array('f', [value1, ..., value100000000])
small_int_array = array('h', [value1, ..., value100000000])
bool_array = array('?', [value1, ..., value100000000])
float2_array = array('f', [value1, ..., value100000000])

ブール配列は、ビットにパックすることでさらに最適化できます。

代わりに、 structinner_listモジュールを使用して要素をバイナリ文字列にパックし、それらを 5 つの異なるリストではなく 1 つのリストに格納することもできます。

3 メモリの解放

変数がスコープ外になるとすぐに、ガベージ コレクションの準備が整うので、メモリを取り戻すことができます。関数やループなどでこれをより早く行うには、リストをダミー値に置き換えて、変数の参照カウントをゼロにします。

variable = None

ノート

ただし、これらのアイデアは、特定のソリューションには十分ではない場合があります。データの一部のみをメモリにロードするなど、他の可能性もあります。それは、どのように処理する予定かによって異なります。

一般に、Python はポインター/構造体の内部処理のために独自のメモリ共有を使用します。したがって、さらに別の方法として、特定のデータ構造とその処理を Fortran、C、または C++ などの言語で実装することもできます。これらの言語は、特定のニーズに合わせてより簡単に調整できます。

于 2012-07-19T03:15:28.357 に答える