2016-08-04 85 views
2

我有一個數組是這樣的:NumPy的/大熊貓:轉換的「臺階」數組布爾面具

arr = np.array([4, 6, 3, 9, 2, 100, 3, 1, 1, 1, 1]) 

我想將它轉換爲布爾數組是這樣的:

[ T, F, F, F, T, F, T, F, F, T, T] 
# 4, 6, 3, 9, 2, 100, 3, 1, 1, 1, 1 

我可以用這樣一個循環做到這一點:

mask = np.zeros(len(arr), dtype=bool) 
ii = 0 
while ii < len(arr): 
    mask[ii] = True 
    ii += arr[ii] 

這有點間接索引方案,其中輸入中的每個元素告訴我們有多少後續元素無效。

如何在不使用Python循環的情況下做到這一點,以便輸入數組很大時它會很快?我也很樂意使用熊貓。

+1

如果我理解正確,這已經很有效率(跳到下一個索引並改變),我無法想象矢量操作會改善這個...我也懷疑'numpy','Pandas'或'scipy'對此有一個內在的東西,但是一個簡單的選擇是用c/C++編寫,用'ctypes'包裝並將'numpy'數組傳遞給你的函數。 –

+0

@EdSmith:循環代碼效率不高,原因很簡單,它使用Python解釋器遍歷值。如果你有很多數據,這可能需要很長時間。 –

+0

我的意思是算法上,如果這是用低級語言編寫的話,那麼在當前形式下它是最優的(似乎是不可矢量化的)?在這種情況下,問題是重新使用一些'numpy' /'pandas'例程比python解釋器開銷更快。 –

回答

2

可能有一些我沒有想到的矢量化技巧,但如果你可以使用numba,它非常適合這樣的問題 - 這個循環現在應該非常快。

import numba 

@numba.jit(nopython=True) 
def jump_mask(arr): 
    mask = np.zeros(len(arr), dtype=np.bool_) 
    ii = 0 
    while ii < len(arr): 
     mask[ii] = True 
     ii += arr[ii] 
    return mask 
+0

我知道Numba,但我希望不需要這個。通常,這些操作可以使用NumPy單獨「旋轉」。 –

+0

是的,我明白儘量避免額外的依賴,但我想不出一種方法來獲得只是numpy/pandas操作的「跳過」,雖然也許是可能的。你可能知道,但這在cython中也很簡單。 – chrisb