2017-08-02 5 views
2

多次元numpy配列のいくつかの部分に読みやすいアクセスが必要です。最初の次元にアクセスする任意の配列に対しては簡単です(b[index])。一方、第6次元へのアクセスは「難しい」(特に読むこと)である。Pythonでn番目の次元にアクセスする

これを行うより良い方法はありますか? 特に、プログラムの作成中に軸がわからない方法はありますか?

編集:

slice = b[..., index] 

答えて

2

は、ビューをしたいと、それは速く、あなただけ手動でインデックスを作成することができますしたい場合:

arr[(slice(None),)*5 + (your_index,)] 
#     ^---- This is equivalent to 5 colons: `:, :, :, :, :` 

わずかに遅く:秒でインデックス化よりもはるかにnp.takeより速く、です:

import numpy as np 

arr = np.random.random((10, 10, 10, 10, 10, 10, 10)) 

np.testing.assert_array_equal(arr[:,:,:,:,:,4], arr.take(4, axis=5)) 
np.testing.assert_array_equal(arr[:,:,:,:,:,4], arr[(slice(None),)*5 + (4,)]) 
%timeit arr.take(4, axis=5) 
# 18.6 ms ± 249 µs per loop (mean ± std. dev. of 7 runs, 10 loops each) 
%timeit arr[(slice(None),)*5 + (4,)] 
# 2.72 µs ± 39.7 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each) 
%timeit arr[:, :, :, :, :, 4] 
# 2.29 µs ± 107 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each) 

しかし、おそらく読んでいない可能性があるので、頻繁にそれを関数w i番目の意味のある名前:MSeifertの答えとkazemakase間(読みやすさと時間的に)

def index_axis(arr, index, axis): 
    return arr[(slice(None),)*axis + (index,)] 

np.testing.assert_array_equal(arr[:,:,:,:,:,4], index_axis(arr, 4, axis=5)) 

%timeit index_axis(arr, 4, axis=5) 
# 3.79 µs ± 127 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each) 
+0

なぜそれが正式な 'np.take'よりも速いのでしょうか? –

+1

@EricDuminil 'np.take'は、通常の索引作成がビューを返す間に(遅い)コピーを作成します(かなり高速です)。 – MSeifert

-1

ではありません。たとえば :

b.take(index, axis=5) 
+1

I私は最後のディメンションのインデックスを作成したいとき、これはうまく動作すると思いますか? –

+1

@JürgMerlinSpaakああ、はい、私はあなたが一般的な最後の次元を意味すると思いました。もし前のようなものが欲しいなら、 'b [...、index、:]'やそれに類することができるかもしれませんが、 'np.take'はもっと明白でしょう。 – jdehesa

5

あなたはnp.takeを使用することができます。 インデックス付きの寸法は、あなたが言うことができ、必ずしも最後の次元

+0

'np.arange(2 ** 6).reshape((2,2,2,2,2,2))。take(1、axis = 5)'私が愚痴を学ぶほど、楽しいです。興味深いもの: –

3

中間の方法はnp.rollaxisを使用している:

np.rollaxis(b, axis=5)[index] 

テストソリューション:

import numpy as np 

arr = np.random.random((10, 10, 10, 10, 10, 10, 10)) 

np.testing.assert_array_equal(arr[:,:,:,:,:,4], arr.take(4, axis=5)) 
np.testing.assert_array_equal(arr[:,:,:,:,:,4], arr[(slice(None),)*5 + (4,)]) 
np.testing.assert_array_equal(arr[:,:,:,:,:,4], np.rollaxis(arr, 5)[4]) 

%timeit arr.take(4, axis=5) 
# 100 loops, best of 3: 4.44 ms per loop 
%timeit arr[(slice(None),)*5 + (4,)] 
# 1000000 loops, best of 3: 731 ns per loop 
%timeit arr[:, :, :, :, :, 4] 
# 1000000 loops, best of 3: 540 ns per loop 
%timeit np.rollaxis(arr, 5)[4] 
# 100000 loops, best of 3: 3.41 µs per loop