2017-03-15 84 views

回答

11
b = a[(slice(None),) * k + (i,)] 

手動構建索引元組。

Python language reference記載,形式

a[:, :, :, :, :, i] 

的表達通過構建元組,而不是直接使用切片表示法轉換爲

a[(slice(None), slice(None), slice(None), slice(None), slice(None), i)] 

我們可以達到同樣的效果。 (有未成年人告誡說,建立元組直接產生a[(i,)],而不是a[i]k=0,但NumPy的處理這些標量i相同)。

+0

Whoaw。我會很樂意複製和粘貼這個,但是鏈接到文檔可能仍然有用。 –

+0

切片符號,例如''a''只是調用'__getitem__'傳遞給它一個元組的語法糖,在這種情況下,是一個切片對象的元組(':'表示法是一個'切片'對象的語法結構) –

+0

還拼寫出'b [np.index_exp [:] * k + np.index_exp [i]]',這可能更具可讀性 – Eric

3

我不知道這是否會對於k昏暗的工作,但它確實爲2暗淡

a.take(i,axis=k) 
+2

這具有創建副本而不是視圖的缺點。 – user2357112

+0

@ user2357112:呵呵,這有點令人驚訝 – Eric

1

基本上,你希望能夠以在通過它爲a指數編程方式創建的元組:, :, :, :, :, i, ...。不幸的是,你不能直接在冒號操作符上直接使用普通的元組乘法運算(即(:,) * k不會生成冒號運算符的元組)。但是,您可以通過使用colon = slice(None)來獲得「冒號切片」的實例。然後你可以做b = a[(colon,) * k + (i,)],這將有效地索引ak第012維的i列。

在函數封裝這件事,你會得到:

def nDimSlice(a, k, i): 
    colon = slice(None) 
    return a[(colon,) * k + (i,)] 
+2

在'n'之後多餘的切片對於numpy來說是不必要的 – Aaron

+0

@Aaron謝謝,我沒有意識到! – user108471

0

我不知道,如果這種方法會創建數組*的整個副本,但我會採取換位一片矩陣,以獲得第k個軸:

import numpy as np 

def get_slice(arr, k, i): 
    if k >= arr.ndim: #we need at least k dimensions (0 indexed) 
     raise ValueError("arr is of lower dimension than {}".format(k)) 

    axes_reorder = list(range(arr.ndim)) #order of axes for transpose 
    axes_reorder.remove(k) #remove original position of k 
    axes_reorder.insert(0,k) #insert k at beginning of order 

    return arr.transpose(axes_reorder)[i] #k is first axis now 

這也有額外的好處在於在嘗試切片之前更容易檢查維數。

*根據docs,只要有可能就會創建一個內存視圖。

1

這裏是遲進入,可處理負軸的參數,而不必知道它的操作數的形狀事先:

def put_at(inds, axis=-1, slc=(slice(None),)): 
    return (axis<0)*(Ellipsis,) + axis*slc + (inds,) + (-1-axis)*slc 

要被用作

a[put_at(ind_list,axis=axis)] 

ind_list可以是標量就像在你的情況或者更有趣的事情一樣。

複製從this評論我的。

相關問題