4

私は大きなマトリックス(250x250x30 = 1,875,000セル)で作業しています。このマトリックスの各セルに任意の数のフラグを設定する方法が必要です。これは、使いやすく、スペース効率に優れた方法です。

私の当初の計画は250x250x30のリスト配列で、各要素は次のようなものでした["FLAG1","FLAG8","FLAG12"]。次に、代わりに整数のみを格納するように変更しました[1,8,12]。これらの整数は、getter/setter関数によって元のフラグ文字列に内部的にマッピングされます。これは、ポイントごとに8つのフラグで250mbのみを使用します。これは、メモリの観点からは問題ありません。

私の質問は、この種のデータを構造化する別の明白な方法が欠けているかどうかです。

ご提案ありがとうございます。私はいくつかの提案を1つにまとめることになりました。悲しいことに、私は1つの答えしか選べず、他の提案に賛成する必要があります。

編集:私がここに持っていた初期コード(3D numpy配列の基本要素としてセットを使用)は、大量のメモリを使用していました。この新しいバージョンは、で埋められたときに約500mbを使用しrandint(0,2**1000)ます。

import numpy

FLAG1=2**0
FLAG2=2**1
FLAG3=2**2
FLAG4=2**3

(x,y,z) = (250,250,30)

array = numpy.zeros((x,y,z), dtype=object)


def setFlag(location,flag):
    array[location] |= flag
def unsetFlag(location,flag):
    array[location] &= ~flag
4

6 に答える 6

7

すべてのセルにフラグが設定されている場合、ソリューションは問題ありません。ただし、セルの小さなサブセクションのみにフラグが設定されているスパースデータセットを使用している場合、本当に必要なのは辞書です。キーがセルの場所のタプルであり、値がソリューションにあるようなフラグのリストになるように、辞書を設定することをお勧めします。

allFlags = {(1,1,1):[1,2,3], (250,250,30):[4,5,6]}

ここでは、1,1,1セルにフラグ1、2、および3があり、セル250、250、30にフラグ4、5、および6があります。

編集-キータプルを修正し、Andreに感謝し、辞書の構文を修正しました。

于 2009-06-29T13:56:34.270 に答える
5

2つの値の累乗が異なるいくつかの定数を次のように定義できます。

FLAG1 = 0x01
FLAG8 = 0x02
FLAG12 = 0x04
...

そして、ブール論理でそれらを使用して、フラグを1つの整数peのみに格納します。

flags = FLAG1 | FLAG8

フラグが有効になっているかどうかを確認するには、次の&演算子を使用できます。

flag1_enabled = flags & FLAG1

フラグが有効になっている場合、この式はゼロ以外の値を返します。これは、ブール演算でTrueと評価されます。フラグが無効になっている場合、式は0を返します。これは、ブール演算ではFalseと評価されます。

于 2009-06-29T14:04:42.117 に答える
5

私は通常、numpy配列(256を超える個別の値が必要になる可能性があるため、それぞれ2バイトの短いint)を使用します。これは、200万未満のセルの場合は4MB未満です。

何らかの理由でnumpyの依存関係を買う余裕がなかった場合(たとえば、numpyをサポートしていないApp Engineの場合)、標準のライブラリ配列モジュールを使用します-これは1次元配列のみをサポートしますが、スペースと同じです-大規模な同種配列のnumpyとして効率的であり、言及したゲッター/セッタールーチンは、自然なインデックスである3項目のタプルを1次元配列の単一の整数インデックスに完全に「線形化」できます。

一般に、大きな同種の密なベクトルまたは数値の行列がある場合は、常にnumpy(または配列)を検討してください。このユースケースでは、Pythonの組み込みリストは、使用していない一般性のために、スペースを非常に浪費します。ここでは必要ありません!-)、そしてメモリを節約することは間接的に時間の節約にもつながります(より良いキャッシング、より少ないレベルの間接参照など)。

于 2009-06-29T14:09:34.743 に答える
3

Flyweightパターンを使用してセルのプロパティを共有することを検討してください。

http://en.wikipedia.org/wiki/Flyweight_pattern

于 2009-06-29T14:00:25.887 に答える
1

BitSetは、固定サイズの整数(Int型)のみを使用して一度に多くのフラグを格納できるため、必要なものです。

于 2009-06-29T13:53:34.713 に答える
1

ロビーの提案をさらに一歩進めて...

flags = set()
x, y, flag = 34, 201, 3
flags.add((x, y, flag)) # set flag 3 at position (34, 201)
if (3, 2, 1) in flags: # check if flag 1 is at position (3, 2)
    # do something
else:
    # do something else

ヘルパークラスを作成することもできます。

class Flags(object):
    def __init__(self):
        self.data = set()
    def add(self, x, y, flag):
        self.data.add((x, y, flag))
    def remove(self, x, y, flag):
        self.data.remove((x, y, flag))
    def contains(self, x, y, flag):
        return (x, y, flag) in self.data

__contains__また、操作を簡単にするなどのPythonの特別なメソッドを実装することもできます。

于 2009-06-29T14:13:39.993 に答える