2017-01-24 223 views
3

從d維數組中選擇所有具有偶數索引的元素,但事先不知道d是否存在高效的pythonic方法?剩下的那些(即所有那些至少有一個奇數指數的)?numpy.array從d維數組中選擇所有偶數元素

的第一個問題的最小示例

import numpy as np 
a = np.array(range(27)).reshape((3,3,3)) 
a[::2,::2,::2] 
# -> array([[[ 0, 2], 
#   [ 6, 8]], 
#   [[18, 20], 
#   [24, 26]]]) 

只有非Python的方式,我發現對於d維物體,D是可變 至少在「所有偶數」部分,該「至少有一個奇怪的「仍然逃避我。

d = 3 
a = np.array(range(3**d)).reshape([3]*d) 
b = a 
for i in range(d): 
    b = np.take(b, np.array(range(0,b.shape[i],2)), axis=i) 

爲什麼我問這(也許早已更高級別的解決方案)的原因是,我要反覆地創建n步大小(2**n+1, ..., 2**n+1)大d的三維物體,在每一步複製從前面的步驟偶數索引的元素,是這樣的:

for n in range(N): 
    new_array = np.zeros([2**n+1]*d) 
    new_array[all_even] = old_array 
    new_array[at_least_one_odd] = #something else 

預先感謝任何提示!

回答

2

下面是一個使用np.ix_的方法 -

a[np.ix_(*[range(0,i,2) for i in a.shape])] 

樣品試驗 -

In [813]: def even_idx(a): 
    ...:  return a[np.ix_(*[range(0,i,2) for i in a.shape])] 
    ...: 

In [814]: a = np.array(range(27)).reshape((3,3,3)) 

In [815]: np.allclose(a[::2,::2,::2], even_idx(a)) 
Out[815]: True 

In [816]: a = np.array(range(27*4)).reshape((3,3,3,4)) 

In [817]: np.allclose(a[::2,::2,::2,::2], even_idx(a)) 
Out[817]: True 

In [818]: a = np.array(range(27*4*5)).reshape((3,3,3,4,5)) 

In [819]: np.allclose(a[::2,::2,::2,::2,::2], even_idx(a)) 
Out[819]: True 
3

我想你可以用切片對象。

even = a[[slice(None, None, 2) for _ in range(a.ndim)]] 
odd = a[[slice(1, None, 2) for _ in range(a.ndim)]] 
+0

感謝您的答案,但不幸的是,當我嘗試運行這個我得到一些警告和錯誤,最基本的是numpy沒有模塊「切片」......雖然@Divakar的答案已經滿足我的需求(至少對於第一個問題,我猜第二個問題沒有令人滿意的答案),你能解釋一下你的答案背後的原理,這對我的理解可能有用嗎?謝謝! –

+1

對不起,切片對象是Python內建的。我更新了我的答案。我想這是更可讀的方式。 – miindlek

+0

非常感謝,它確實很棒!我不知道有一個「片」內置代替片:符號,這確實很有用。爲了澄清,問題的第二部分是讓元素至少有一個奇怪的索引,而不是所有的可能性;在這個例子中,有27個元素,其中8個甚至是我天真地希望得到剩下的19個元素(當它們失去任何形狀時,這個元素必然是扁平的)。但是再次,我越想越覺得它似乎越來越不合理,因此我對第一部分感到非常滿意,謝謝! –