<p>下面是另一种通过数组赋值跳过重复部分的方法-</p>
<pre><code>def func1(a):
l = a.sum()
out = np.full(l, -1, dtype=int)
out[0] = a[0]-1
idx = a.cumsum()[:-1]
out[idx] = a[1:]-1
return out.cumsum()
</code></pre>
<h3>基准测试</h3>
<pre><code># OP's soln
def OP(x):
y = np.repeat(x, x)
t = -np.ones(y.shape[0], dtype=int)
t[np.r_[0, np.cumsum(x)[:-1]]] = x-1
return np.cumsum(t)
</code></pre>
<p>使用<a href="https://github.com/droyed/benchit" rel="nofollow noreferrer">^{<cd1>}</a>包(打包在一起的一些基准测试工具;免责声明:我是它的作者)对建议的解决方案进行基准测试</p>
<pre><code>import benchit
a = np.array([3,4,2,2,1,3,1])
in_ = [np.resize(a,n) for n in [10, 100, 1000, 10000]]
funcs = [OP, func1]
t = benchit.timings(funcs, in_)
t.plot(logx=True, save='timings.png')
</code></pre>
<p><a href="https://i.stack.imgur.com/LKmqT.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/LKmqT.png" alt="enter image description here"/></a></p>
<p><strong>扩展以<code>k</code>作为arg</strong></p>
<pre><code>def func1(a, k):
l = a.sum()+len(a)*(-k)
out = np.full(l, -1, dtype=int)
out[0] = a[0]-1
idx = (a-k).cumsum()[:-1]
out[idx] = a[1:]-1-k
return out.cumsum()
</code></pre>
<p>样本运行-</p>
<pre><code>In [120]: a
Out[120]: array([3, 4, 2, 2, 1, 3, 1])
In [121]: func1(a, k=-1)
Out[121]:
array([ 2, 1, 0, -1, 3, 2, 1, 0, -1, 1, 0, -1, 1, 0, -1, 0, -1,
2, 1, 0, -1, 0, -1])
</code></pre>