<p>2种可能的方法<code>sawtooth1</code>使用与@sai相同的思想</p>
<pre><code>import numpy as np
arr = np.array([ 1,1,1,1,1,-1,-1,-1,-1,1,1,1,1,-1,-1,-1])
arr
# Out[3]: array([ 1, 1, 1, 1, 1, -1, -1, -1, -1, 1, 1, 1, 1, -1, -1, -1])
def sawtooth0( arr ):
cumsum_ix = np.zeros_like(arr)
cumsum_ix[ 1: ] = (( arr[ :-1 ] - arr[ 1: ] ) != 0 ).cumsum()
# cumsum_ix incrememnts for each sign change.
result = np.zeros_like( arr )
for i in range( 0, cumsum_ix[ -1 ] + 1 ):
# For each cumsum_ix select those items and generate the cumsums.
result[ cumsum_ix==i ] = arr[ cumsum_ix==i ].cumsum()
return result
sawtooth0( arr )
# Out[21]: array([ 1, 2, 3, 4, 5, -1, -2, -3, -4, 1, 2, 3, 4, -1, -2, -3])
def sawtooth1( arr ):
cumsum_ix = np.zeros_like(arr)
cumsum_ix[ 1: ] = (( arr[ :-1 ] - arr[ 1: ] ) != 0 ).cumsum()
# cumsum_ix incrememnts for each sign change.
totals = np.zeros( cumsum_ix[ -1 ] + 1, dtype = np.int )
for i in range( 0, cumsum_ix[ -1 ] ):
# For each cumsum_ix select those items and generate the sum.
totals[ i+1 ] = arr[ cumsum_ix == i ].sum()
totals = totals.cumsum()
return arr.cumsum() - totals[ cumsum_ix ]
# subtract the cumulative previous totalsfor each
sawtooth1( arr )
# Out[22]: array([ 1, 2, 3, 4, 5, -1, -2, -3, -4, 1, 2, 3, 4, -1, -2, -3])
</code></pre>
<p>两者的时间差是微不足道的</p>