あなたは次のようなことを話していると思います:
In [398]: A=np.arange(24).reshape(4,6)
In [401]: I=np.array([[0,1],[1,2],[3,4],[0,0],[2,5]])
In [402]: tuple(I.T)
Out[402]: (array([0, 1, 3, 0, 2]), array([1, 2, 4, 0, 5]))
In [403]: A[tuple(I.T)]
Out[403]: array([ 1, 8, 22, 0, 17])
これはhttp://docs.scipy.org/doc/numpy/reference/arrays.indexing.html#purely-integer-array-indexing - 純粋な整数配列の高度なインデックス付けです。
これは、ビューを返す基本的なインデックス作成よりも常に遅くなります。基本的なインデックス作成では、連続したデータ ブロック、またはストライドで選択できる値が選択されます。これは、インデックス作成では不可能です。
いくつかのタイミングを見てください:
In [404]: timeit tuple(I.T)
100000 loops, best of 3: 3.4 µs per loop
In [405]: timeit A[tuple(I.T)]
100000 loops, best of 3: 10 µs per loop
In [406]: %%timeit i,j=tuple(I.T)
.....: A[i,j]
.....:
100000 loops, best of 3: 4.86 µs per loop
タプルの構築には約 1/3 の時間がかかります。 i,j=I.T
は少しだけ速いです。しかし、そのインデックス作成は最大のピースです。
A[i,j]
A[(i,j)]
は(そのまま)と同じA.__getitem__((i,j))
です。したがって、ラップI.T
するtuple
と、各次元に 1 つずつ、2 つのインデックス配列が生成されます。
フラット化されたバージョンの配列にインデックスを付ける方が高速です。
In [420]: J= np.ravel_multi_index(tuple(I.T),A.shape)
In [421]: J
Out[421]: array([ 1, 8, 22, 0, 17], dtype=int32)
In [422]: A.flat[J]
Out[422]: array([ 1, 8, 22, 0, 17])
In [425]: timeit A.flat[J]
1000000 loops, best of 3: 1.56 µs per loop
In [426]: %%timeit
.....: J= np.ravel_multi_index(tuple(I.T),A.shape)
.....: A.flat[J]
.....:
100000 loops, best of 3: 11.2 µs per loop
したがって、インデックスを事前計算して再利用できると時間を節約できますが、個々の値の束を選択するのにA
余分な時間がかかるという事実を理解する方法はありません。
楽しみのために、インデックス作成にかかる時間をA
の各行と比較してみましょうI
:
In [442]: timeit np.array([A[tuple(i)] for i in I])
100000 loops, best of 3: 17.3 µs per loop
In [443]: timeit np.array([A[i,j] for i,j in I])
100000 loops, best of 3: 15.7 µs per loop