編集私は以下に直面しているより複雑な問題を保持していますが、私の問題はnp.take
次のように要約できます。shapeの配列と shapeimg
の(planes, rows)
別の配列があり、それらを使用してshapeの新しい配列を作成するとします。これは、次のようにファンシー インデックスを使用して実現できます。lut
(planes, 256)
out
(planes, rows)
out[p,j] = lut[p, img[p, j]]
In [4]: %timeit lut[np.arange(planes).reshape(-1, 1), img]
1000 loops, best of 3: 471 us per loop
しかし、派手なインデックス作成の代わりに、take を使用し、物事に対する python ループをplanes
大幅に高速化することができます。
In [6]: %timeit for _ in (lut[j].take(img[j]) for j in xrange(planes)) : pass
10000 loops, best of 3: 59 us per loop
Pythonループなしで操作全体を実行できるように、何らかの方法で再配置できますが、速度の利点を維持するために従来の派手なインデックス作成の代わりに(または代替方法)を使用しlut
ますか?img
numpy.take
元の質問
画像で使用したい一連のルックアップ テーブル (LUT) があります。LUT を保持する配列は shape(planes, 256, n)
であり、イメージは shape(planes, rows, cols)
です。どちらも で、LUT の軸にdtype = 'uint8'
一致します。256
アイデアは、 LUT の -th プレーンから各 LUTp
を介してイメージの -th プレーンを実行することです。n
p
私のlut
とimg
が次の場合:
planes, rows, cols, n = 3, 4000, 4000, 4
lut = np.random.randint(-2**31, 2**31 - 1,
size=(planes * 256 * n // 4,)).view('uint8')
lut = lut.reshape(planes, 256, n)
img = np.random.randint(-2**31, 2**31 - 1,
size=(planes * rows * cols // 4,)).view('uint8')
img = img.reshape(planes, rows, cols)
このような派手なインデックス作成を使用した後、私は何を達成できますか
out = lut[np.arange(planes).reshape(-1, 1, 1), img]
これにより、 shape の配列が得られます(planes, rows, cols, n)
。ここで、 LUT の -th プレーンの -th LUT を介して実行される-th プレーンがout[i, :, :, j]
保持されます...i
img
j
i
これを除いて、すべてが良いです:
In [2]: %timeit lut[np.arange(planes).reshape(-1, 1, 1), img]
1 loops, best of 3: 5.65 s per loop
np.take
これは完全に受け入れられません。特に、実行速度が大幅に向上するよりも、見栄えの悪い次の代替手段をすべて使用しているためです。
1 つのプレーンで 1 つの LUT を実行すると、約 70 倍高速に実行されます。
In [2]: %timeit np.take(lut[0, :, 0], img[0]) 10 loops, best of 3: 78.5 ms per loop
必要なすべての組み合わせを実行する Python ループは、ほぼ 6 倍速く終了します。
In [2]: %timeit for _ in (np.take(lut[j, :, k], img[j]) for j in xrange(planes) for k in xrange(n)) : pass 1 loops, best of 3: 947 ms per loop
LUT と画像でプレーンのすべての組み合わせを実行してから、
planes**2 - planes
不要なものを破棄することは、手の込んだインデックス作成よりも高速です。In [2]: %timeit np.take(lut, img, axis=1)[np.arange(planes), np.arange(planes)] 1 loops, best of 3: 3.79 s per loop
そして、私が思いついた最速の組み合わせには、プレーンを反復処理する Python ループがあり、x13 をより速く終了します。
In [2]: %timeit for _ in (np.take(lut[j], img[j], axis=0) for j in xrange(planes)) : pass 1 loops, best of 3: 434 ms per loop
np.take
もちろん問題は、Pythonループなしでこれを行う方法がないかどうかです? 理想的には、必要な再形成またはサイズ変更は、画像ではなく LUT で行われる必要がありますが、私はあなたが思いつくものは何でも受け入れます...