我有以下的熊貓系列(表示爲列表):如何計算熊貓系列中前一個零點的距離?
[7,2,0,3,4,2,5,0,3,4]
我想定義一個新的系列,返回到最後零距離。這意味着,我想有以下輸出:
[1,2,0,1,2,3,4,0,1,2]
如何做到這一點的大熊貓最有效的方法是什麼?
我有以下的熊貓系列(表示爲列表):如何計算熊貓系列中前一個零點的距離?
[7,2,0,3,4,2,5,0,3,4]
我想定義一個新的系列,返回到最後零距離。這意味着,我想有以下輸出:
[1,2,0,1,2,3,4,0,1,2]
如何做到這一點的大熊貓最有效的方法是什麼?
看到使用Cython來獲得這種東西的c-like速度有多簡單,這有時讓人驚訝。假設你列的.values
給arr
,則:
cdef int[:, :, :] arr_view = arr
ret = np.zeros_like(arr)
cdef int[:, :, :] ret_view = ret
cdef int i, zero_count = 0
for i in range(len(ret)):
zero_count = 0 if arr_view[i] == 0 else zero_count + 1
ret_view[i] = zero_count
注意使用typed memory views,這是非常快。您可以使用此功能使用@cython.boundscheck(False)
進行進一步加速。
在大熊貓一種解決方案是一個有點棘手,但看起來是這樣的(s
是您的系列):
>>> x = (s != 0).cumsum()
>>> y = x != x.shift()
>>> y.groupby((y != y.shift()).cumsum()).cumsum()
0 1
1 2
2 0
3 1
4 2
5 3
6 4
7 0
8 1
9 2
dtype: int64
對於最後一個步驟,這裏採用的大熊貓「itertools.groupby」食譜食譜here。
複雜度爲O(n)
。什麼會減慢它在Python中執行for
循環。如果有k
零在系列,和log k
是negligibile比較序列的長度,一個O(n log k)
的解決辦法是:
>>> izero = np.r_[-1, (ts == 0).nonzero()[0]] # indices of zeros
>>> idx = np.arange(len(ts))
>>> idx - izero[np.searchsorted(izero - 1, idx) - 1]
array([1, 2, 0, 1, 2, 3, 4, 0, 1, 2])
我欣賞優雅,但這執行大量遍+一個''GROUPBY ',對於那些在單遍Cython擴展中如此微不足道的東西。 –
我同意 - 如果性能很重要,這種類型的東西在Cython中實現會更好。在Pandas中可以做到這一點(如食譜所示),如果Cython不是可用的選項,這很方便。 –