<p>这里有一种使用<a href="http://scikit-image.org/docs/dev/api/skimage.util.html#skimage.util.view_as_windows" rel="nofollow noreferrer">^{<cd1>}'s ^{<cd2>}</a>的方法,可以有效地提取滑动窗口。在</p>
<p>涉及的步骤:</p>
<ul>
<li><p>推拉窗户。</p></li>
<li><p>重塑为二维阵列。{但是我们要保持这个向量化的效率。</p></li>
<li><p>沿合并块轴的轴排序。</p></li>
<li><p>沿着这个轴求微分并计算不同元素的数量,当加上<code>1</code>时,这将是每个滑动窗口中唯一值的计数,从而得到最终的预期结果。</p></li>
</ul>
<p>执行方式如下-</p>
<pre><code>from skimage.util import view_as_windows as viewW
def sliding_uniq_count(a, BSZ):
out_shp = np.asarray(a.shape) - BSZ + 1
a_slid4D = viewW(a,BSZ)
a_slid2D = np.sort(a_slid4D.reshape(-1,np.prod(BSZ)),axis=1)
return ((a_slid2D[:,1:] != a_slid2D[:,:-1]).sum(1)+1).reshape(out_shp)
</code></pre>
<p>样本运行-</p>
^{pr2}$
<p><strong>混合方法</strong></p>
<p>为了使它能与非常大的数组一起工作,为了将所有内容都放入内存中,我们可能需要保持一个循环,它将沿着输入数据的每一行进行迭代,如下-</p>
<pre><code>def sliding_uniq_count_oneloop(a, BSZ):
S = np.prod(BSZ)
out_shp = np.asarray(a.shape) - BSZ + 1
a_slid4D = viewW(a,BSZ)
out = np.empty(out_shp,dtype=int)
for i in range(a_slid4D.shape[0]):
a_slid2D_i = np.sort(a_slid4D[i].reshape(-1,S),-1)
out[i] = (a_slid2D_i[:,1:] != a_slid2D_i[:,:-1]).sum(-1)+1
return out
</code></pre>
<p><strong>混合方法-第二版</p>
<p>混合1的另一个版本,显式使用<code>np.lib.stride_tricks.as_strided</code>-</p>
<pre><code>def sliding_uniq_count_oneloop(a, BSZ):
S = np.prod(BSZ)
out_shp = np.asarray(a.shape) - BSZ + 1
strd = np.lib.stride_tricks.as_strided
m,n = a.strides
N = out_shp[1]
out = np.empty(out_shp,dtype=int)
for i in range(out_shp[0]):
a_slid3D = strd(a[i], shape=((N,) + tuple(BSZ)), strides=(n,m,n))
a_slid2D_i = np.sort(a_slid3D.reshape(-1,S),-1)
out[i] = (a_slid2D_i[:,1:] != a_slid2D_i[:,:-1]).sum(-1)+1
return out
</code></pre>