上記の unutbu の長い回答を拡張すると、マスクされたスコアの配列を自動的に生成することができます。値のスコアはループを通過するたびに一貫しているため、各値のスコアは 1 回だけ計算する必要があります。スコアが適用される前と後に、例の 6x10 配列でそれを行う少し洗練されていない方法を次に示します。
>>> import numpy
>>> values = numpy.random.randint(6, size=(6,10))
>>> values
array([[4, 5, 1, 2, 1, 4, 0, 1, 0, 4],
[2, 5, 2, 2, 3, 1, 3, 5, 3, 1],
[3, 3, 5, 4, 2, 1, 4, 0, 0, 1],
[2, 4, 0, 0, 4, 1, 4, 0, 1, 0],
[0, 4, 1, 2, 0, 3, 3, 5, 0, 1],
[2, 3, 3, 4, 0, 1, 1, 1, 3, 2]])
>>> b = values.copy()
>>> b[ b<3 ] = -1
>>> b[ b==3 ] = 0
>>> b[ b>3 ] = 1
>>> b
array([[ 1, 1, -1, -1, -1, 1, -1, -1, -1, 1],
[-1, 1, -1, -1, 0, -1, 0, 1, 0, -1],
[ 0, 0, 1, 1, -1, -1, 1, -1, -1, -1],
[-1, 1, -1, -1, 1, -1, 1, -1, -1, -1],
[-1, 1, -1, -1, -1, 0, 0, 1, -1, -1],
[-1, 0, 0, 1, -1, -1, -1, -1, 0, -1]])
ちなみに、このスレッドは、numpy 内で直接組み合わせを作成すると、おそらく読みやすさが犠牲になるものの、itertools よりも約 5 倍高速なパフォーマンスが得られると主張しています。