私はあなたの痛みを感じます...後で破棄する値に配列のサイズの数倍を格納することになることがあります。配列内の 1 つの項目を一度に処理する場合、これは無関係ですが、ベクトル化するときに失敗する可能性があります。
説明のために仕事の例を使用します。私は最近、ここで説明するアルゴリズムを numpy を使用してコーディングしました。RGB 画像を CMYK 画像に変換するカラー マップ アルゴリズムです。ピクセルごとに繰り返されるプロセスは次のとおりです。
- すべての RGB 値の最上位 4 ビットを、3 次元ルックアップ テーブルのインデックスとして使用します。これにより、LUT 内の立方体の 8 つの頂点の CMYK 値が決まります。
- 前の手順の頂点値に基づいて、すべての RGB 値の最下位 4 ビットを使用して、そのキューブ内で補間します。これを行う最も効率的な方法は、処理される画像のサイズの uint8 の 16 個の配列を計算することです。24 ビット RGB 画像の場合、処理するために画像の x6 倍のストレージが必要になるのと同じです。
これを処理するためにできることがいくつかあります。
1.分割統治
1,000x1,000 の配列を 1 回のパスで処理できない場合があります。しかし、100x1,000 の 10 個の配列を反復する python for ループでそれを実行できる場合でも、1,000,000 項目を超える python イテレーターよりはるかに優れています! はい、遅くなりますが、それほどではありません。
2. 高価な計算をキャッシュする
これは、上記の補間の例に直接関係しており、見つけにくいですが、目を光らせておく価値があります。各次元に 4 ビットの 3 次元立方体を補間しているため、16x16x16 バイトの 16 個の配列に格納できる結果は 16x16x16 しかありません。したがって、それらを事前に計算して 64KB のメモリを使用して格納し、画像全体の値を 1 つずつ検索することができます。メモリを大量に消費してすべてのピクセルに対して同じ操作をやり直す必要はありません。これは、64x64 ピクセル程度の小さな画像にはすでに効果があり、基本的に、配列を再分割することなく、ピクセル量の x6 倍の画像を処理できます。
3.dtypes
賢く使う
中間値が単一の に収まる場合はuint8
、 の配列を使用しないでくださいint32
。これは、サイレントオーバーフローによる不可解なエラーの悪夢に変わる可能性がありますが、注意すれば、リソースを大幅に節約できます。