<p>这里有一种使用<code>masking</code>和<code>maximum-accumulation</code>与<code>np.maximum.accumulate</code>的矢量化方法-</p>
<pre><code>i[np.maximum.accumulate(np.where(a==0, np.arange(len(a)), 0))]
</code></pre>
<p>另一种说法是-</p>
<pre><code>i[np.maximum.accumulate(np.arange(len(a)) * (a==0))]
</code></pre>
<p><strong>解释</strong></p>
<p>为了深入了解故事的细节,我们来分解一下步骤-</p>
<p>1]输入:</p>
<pre><code>In [83]: a = np.array([0, 1, 1, 1, 0, 0, 0, 1, 1, 0, 1])
...: i = np.array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10])
...:
</code></pre>
<p>2]所以,输入<code>a</code>是:</p>
<pre><code>In [84]: a
Out[84]: array([0, 1, 1, 1, 0, 0, 0, 1, 1, 0, 1])
</code></pre>
<p>3]获取覆盖长度为<code>a</code>的范围数组:</p>
<pre><code>In [85]: np.arange(len(a))
Out[85]: array([ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10])
</code></pre>
<p>4]现在在a为1的位置屏蔽范围数组,留下与a为0对应的元素:</p>
<pre><code>In [86]: np.arange(len(a)) * (a==0)
Out[86]: array([0, 0, 0, 0, 4, 5, 6, 0, 0, 9, 0])
</code></pre>
<p>5]根据需要使用最大累积量来创建斜坡结构:</p>
<pre><code>In [87]: np.maximum.accumulate(np.arange(len(a)) * (a==0))
Out[87]: array([0, 0, 0, 0, 4, 5, 6, 6, 6, 9, 9])
</code></pre>
<p>6]最后用这些数字索引到i中,以获得所需的输出:</p>
<pre><code>In [88]: i[np.maximum.accumulate(np.arange(len(a)) * (a==0))]
Out[88]: array([0, 0, 0, 0, 4, 5, 6, 6, 6, 9, 9])
</code></pre>
<p><strong>运行时测试</p>
<p>接近-</p>
<pre><code>def FranciscoRodriguez(a,i): # @Francisco Rodríguez's soln
x = []
for idx,val in enumerate(a):
if val==0: x.append(i[idx])
elif val==1: x.append(x[-1])
return x
def ThomasGuenet(a,i): # @ThomasGuenet 's soln
x = np.zeros(len(a))
for j, aa in enumerate(a):
if j == 0:
x[j] == aa
elif aa == 1:
x[j] = x[j-1]
else:
x[j] = i[j]
return x
def vectorizedApp1(a,i):
return i[np.maximum.accumulate(np.where(a==0, np.arange(len(a)), 0))]
def vectorizedApp2(a,i):
return i[np.maximum.accumulate(np.arange(len(a)) * (a==0))]
</code></pre>
<p>计时-</p>
<p>让我们平铺给定的示例以创建更大的数据集,并测试所有解决方案:</p>
<pre><code>In [78]: a = np.array([0, 1, 1, 1, 0, 0, 0, 1, 1, 0, 1])
...: i = np.array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10])
...:
...: a = np.tile(a,100000)
...: i = np.tile(i,100000)
...:
In [79]: %timeit FranciscoRodriguez(a,i)
...: %timeit ThomasGuenet(a,i)
...: %timeit vectorizedApp1(a,i)
...: %timeit vectorizedApp2(a,i)
...:
1 loop, best of 3: 328 ms per loop
1 loop, best of 3: 331 ms per loop
100 loops, best of 3: 6.07 ms per loop
100 loops, best of 3: 6.77 ms per loop
</code></pre>