2

最大で1000x1000 x 1000の要素が含まれますが、これはPython辞書には大きすぎます。

辞書を使用すると、約30 x 1000 x 1000の要素があり、私のマシンではすでに2 GBのメモリを消費し、すべてが石になってしまいました。

値がTrue/Falseのみになる3次元配列を処理できるモジュールはありますか?私はbitarrayhttp : //pypi.python.org/pypi/bitarrayをチェックします。これは合理的で、Cでコーディングされているように見えますが、1次元しかサポートしていないため、配列ではなくビットストリームのように見えます。

4

4 に答える 4

6

numpyはあなたの友達です:

import numpy as np
a = np.zeros((1000,1000,1000), dtype=bool)
a[1,10,100] = True

メモリーフットプリントは可能な限り少なくなります。

編集:

本当に必要な場合は、collectionsモジュールのdefaultdictクラスコンテナを確認することもできます。このコンテナには、デフォルト値の値は格納されていません。しかし、それが本当に必須ではない場合は、numpyを使用してください。

于 2012-11-28T21:13:03.590 に答える
2

おそらく素晴らしいAPIを使用して独自のクラスにラップされたビット配列のリストのリストはどうですか?

または、整数の3D NumPy配列で、各整数に複数のブール値をパック/アンパックする独自のコードを使用します。

于 2012-11-28T21:12:08.243 に答える
1

numpyEnricoGiampieriによってすでに提案されており、これを使用できる場合は、そうする必要があります。

それ以外の場合は、2つの選択肢があります。

NPEによって提案されているように、ジャグ配列はsのalistになります。これにより、ギザギザの境界を設定できます。たとえば、各行の幅を変えたり、個別にサイズを変更したりできます。listbitarray

bits3d = [[bitarray.bitarray(1000) for y in range(1000)] for x in range(1000)]
myvalue = bits3d[x][y][z]

または、Xymostechが提案しているように、1-D配列で独自のインデックスを作成します。

bits3d = bitarray.bitarray(1000*1000*1000)
myvalue = bits3d[x + y*1000 + z*1000*1000]

いずれにせよ、おそらくこれをクラスにまとめたいと思うので、これを行うことができます。

bits3d = BitArray(1000, 1000, 1000)
myvalue = bits3d[x, y, z]

それは次のように簡単です:

class Jagged3DBitArray(object):
    def __init__(self, xsize, ysize, zsize):
        self.lll = [[bitarray(zsize) for y in range(ysize)] 
                    for x in range(xsize)]
    def __getitem__(self, key):
        x, y, z = key
        return self.lll[x][y][z]
    def __setitem__(self, key, value):
        x, y, z = key
        self.lll[x][y][z] = value

class Fixed3DBitArray(object):
    def __init__(self, xsize, ysize, zsize):
        self.xsize, self.ysize, self.zsize = xsize, ysize, zsize
        self.b = bitarray(xsize * ysize * zsize)
    def __getitem__(self, key):
        x, y, z = key
        return self.b[x + y * self.ysize + z * self.ysize * self.zsize]
    def __setitem__(self, key, value):
        x, y, z = key
        self.b[x + y * self.ysize + z * self.ysize * self.zsize] = value

もちろん、より多くの機能(スライスなど)が必要な場合は、もう少し書く必要があります。

ジャグ配列はもう少し多くのメモリを使用し(結局のところ、1Mbitarrayオブジェクトと1Klistオブジェクトのオーバーヘッドがあります)、少し遅くなる可能性がありますが、通常、これは大きな違いにはなりません。

重要な決定要因は、データにギザギザの行があることが本質的にエラーであるかどうかです。その場合は、2番目のソリューションを使用してください。ギザギザまたはサイズ変更可能な行があると便利な場合は、前者を使用してください。numpy(可能であれば、どちらのソリューションでも使用することを念頭に置いてください。)

于 2012-11-28T22:01:38.003 に答える
0

UNIXファイルのパーミッションに触発されてみませんか?755所有者に対して読み取り、書き込み、実行し、他のすべての人に対して読み取り、実行します。これは、7バイナリに変換されるため111です。

したがって、1000x1000x1000のbool配列は、intsの1000x1000リストであり、各intのバイナリ表現により、bool配列を表す1000の「ビット」文字列が得られます。

そのすべてが1GB未満のメモリに収まるはずです

于 2012-11-28T21:16:48.063 に答える