大きな(1,000,000 x 3,000)ブール値のnumpy配列全体でインデックス付きの重みの合計を計算したいと思います。大きなブール配列はめったに変更されませんが、重みはクエリ時に発生するため、大きな配列全体をコピーしたり、小さな重みの配列を大きな配列のサイズに拡張したりせずに、非常に高速に回答する必要があります。
結果は、1,000,000エントリの配列になります。各エントリには、その行のTrue値に対応する重み配列エントリの合計が含まれます。
マスクされた配列の使用を検討しましたが、大きなブール配列のサイズの重み配列を作成する必要があるようです。
以下のコードは正しい結果を示していますが、乗算ステップ中にそのコピーを購入する余裕はありません。値の配列はブール値であるため、乗算は必要ありませんが、少なくともブロードキャストを適切に処理します。
私はnumpyに不慣れで、それを愛していますが、この特定の問題のためにそれをあきらめようとしています。私は、Pythonでループするものから離れることを知るのに十分な数を学びました。
次のステップは、このルーチンをCで作成することです(ちなみに、バイトではなくビットを使用してメモリを節約できるという追加の利点があります)。
あなたのだらしない教祖の一人が私をcythonから救うことができない限り?
from numpy import array, multiply, sum
# Construct an example values array, alternating True and False.
# This represents four records of three attributes each:
# array([[False, True, False],
# [ True, False, True],
# [False, True, False],
# [ True, False, True]], dtype=bool)
values = array([(x % 2) for x in range(12)], dtype=bool).reshape((4,3))
# Construct example weights, one for each attribute:
# array([1, 2, 3])
weights = array(range(1, 4))
# Create expensive NEW array with the weights for the True attributes.
# Broadcast the weights array into the values array.
# array([[0, 2, 0],
# [1, 0, 3],
# [0, 2, 0],
# [1, 0, 3]])
weighted = multiply(values, weights)
# Add up the weights:
# array([2, 4, 2, 4])
answers = sum(weighted, axis=1)
print answers
# Rejected masked_array solution is too expensive (and oddly inverts
# the results):
masked = numpy.ma.array([[1,2,3]] * 4, mask=values)