<p>这是一个使用where的直接方法。从查找匹配项的逻辑表达式开始:</p>
<pre><code>In [670]: values = np.array([0,1,2,1,2,4,5,6,1,2,1])
...: searchval = [1,2]
...:
In [671]: (values[:-1]==searchval[0]) & (values[1:]==searchval[1])
Out[671]: array([False, True, False, True, False, False, False, False, True, False], dtype=bool)
In [672]: np.where(_)
Out[672]: (array([1, 3, 8], dtype=int32),)
</code></pre>
<p>它可以被概括为一个在多个<code>searchval</code>上操作的循环。正确的切片范围需要一些技巧。在另一个答案中建议的<code>roll</code>可能更容易,但我怀疑有点慢。</p>
<p>只要<code>searchval</code>比<code>values</code>小,这种一般方法就应该是有效的。有一个<code>np.in1d</code>进行这种匹配,但是有一个<code>or</code>测试。所以不适用。但它也使用了这种迭代方法,即<code>searchval</code>列表足够小。</p>
<h2>广义切片</h2>
<pre><code>In [716]: values
Out[716]: array([0, 1, 2, 1, 2, 4, 5, 6, 1, 2, 1])
In [717]: searchvals=[1,2,1]
In [718]: idx = [np.s_[i:m-n+1+i] for i in range(n)]
In [719]: idx
Out[719]: [slice(0, 9, None), slice(1, 10, None), slice(2, 11, None)]
In [720]: [values[idx[i]] == searchvals[i] for i in range(n)]
Out[720]:
[array([False, True, False, True, False, False, False, False, True], dtype=bool),
array([False, True, False, True, False, False, False, False, True], dtype=bool),
array([False, True, False, False, False, False, True, False, True], dtype=bool)]
In [721]: np.all(_, axis=0)
Out[721]: array([False, True, False, False, False, False, False, False, True], dtype=bool)
In [722]: np.where(_)
Out[722]: (array([1, 8], dtype=int32),)
</code></pre>
<p>我用中间体<code>np.s_</code>来观察切片,确保它们看起来合理。</p>
<h2>大步前进</h2>
<p>一个高级技巧是使用<code>as_strided</code>构造“rolled”数组并对其执行2d<code>==</code>测试。<code>as_strided</code>很整洁但很棘手。要正确使用它,你必须了解步伐,并得到正确的形状。</p>
<pre><code>In [740]: m,n = len(values), len(searchvals)
In [741]: values.shape
Out[741]: (11,)
In [742]: values.strides
Out[742]: (4,)
In [743]:
In [743]: M = as_strided(values, shape=(n,m-n+1),strides=(4,4))
In [744]: M
Out[744]:
array([[0, 1, 2, 1, 2, 4, 5, 6, 1],
[1, 2, 1, 2, 4, 5, 6, 1, 2],
[2, 1, 2, 4, 5, 6, 1, 2, 1]])
In [745]: M == np.array(searchvals)[:,None]
Out[745]:
array([[False, True, False, True, False, False, False, False, True],
[False, True, False, True, False, False, False, False, True],
[False, True, False, False, False, False, True, False, True]], dtype=bool)
In [746]: np.where(np.all(_,axis=0))
Out[746]: (array([1, 8], dtype=int32),)
</code></pre>