<p>下面是一个基于将数组重新划分为iterable窗口的答案:</p>
<pre><code>import numpy as np
from numpy.lib.stride_tricks import as_strided
def windowstride(a, window):
return as_strided(a, shape=(a.size - window + 1, window), strides=2*a.strides)
def local_min(a, maxwindow=None, doends=True):
if doends: a = np.pad(a.astype(float), 1, 'constant', constant_values=np.inf)
if maxwindow is None: maxwindow = a.size - 1
mins = []
for i in range(3, maxwindow + 1):
for j,w in enumerate(windowstride(a, i)):
if (w[0] > w[1]) and (w[-2] < w[-1]):
if (w[1:-1]==w[1]).all():
mins.append((j, j + i - 2))
mins.sort()
return mins
</code></pre>
<p>测试一下:</p>
^{pr2}$
<p>输出:</p>
<pre><code>[(0, 2), (3, 6), (9, 10), (11, 13), (15, 17)]
</code></pre>
<p>不是最有效的算法,但至少它很短。我很确定它是<code>O(n^2)</code>,因为有大约<code>1/2*(n^2 + n)</code>个窗口需要迭代。这只是部分矢量化,所以可能有一种方法可以改进它。在</p>
<h3>编辑</h3>
<p>为了澄清,输出是包含局部最小值运行的切片的索引。事实上,他们超过了运行的结束是故意的(有人只是试图在编辑中“修复”这个问题)。可以使用输出迭代输入数组中最小值的片段,如下所示:</p>
<pre><code>for s in local_mins(test03):
print(test03[slice(*s)])
</code></pre>
<p>输出:</p>
<pre><code>[2 2]
[4 4 4]
[2]
[5 5]
[1 1]
</code></pre>