在numpy中查找分隔的最大值

时间:2019-05-29 12:57:51

标签: python numpy optimization scipy

给出一个numpy ndarray,如何找到所有峰,但是每个峰之间的距离至少应保持一定距离。原因是通常有一个峰,然后接下来的许多峰只是第一个峰的相邻点,因此它们不是任何“新”峰。

我确信必须有更好的实现,这就是我要的。 为了说明我想要的内容,下面是一个示例示例,我将它们放在一起(我进行了编辑以改进示例,并在最后添加了图像):

import numpy as np
from matplotlib import pyplot as plt
import scipy as sp
import scipy.ndimage
def findpeaks(objective, maxpeaks=10, gap=0):
    obj = objective.copy()
    peaks = np.zeros([maxpeaks, 2], dtype=int)
    for n in range(maxpeaks):
        peak = np.unravel_index(np.argmax(obj, axis=None), obj.shape)
        peaks[n,:] = peak
        obj[np.maximum(0,peak[0]-gap):np.minimum(40,peak[0]+gap),
            np.maximum(0,peak[1]-gap):np.minimum(40,peak[1]+gap)] = 0
    return peaks

np.random.seed(12345)
x = np.random.uniform(0, 1, [40,40])
x = sp.ndimage.filters.gaussian_filter(x, [3,3], mode='constant')

peaks = findpeaks(x, 10, 5)
print(peaks.T)
print(x[peaks[:,0],peaks[:,1]])
print(np.array(np.unravel_index(x.flatten().argsort()[-10:][::-1],x.shape)))
for p in peaks:
    x[p[0]-1:p[0]+2,p[1]]=0
    x[p[0],p[1]-1:p[1]+2]=0
plt.imshow(x, cmap='gray')

输出为

[[27 11 26 24  5 16 25 16 13 31]
 [11 14 16  5 13 34 21 14  8 16]]
[0.55472915 0.54961331 0.53829221 0.5353206  0.53512158 0.52064241
 0.51729225 0.51557288 0.51025817 0.50846277]
[[27 27 26 28 27 28 26 27 26 11]
 [11 12 11 11 10 12 12 13 10 14]]

The x array and its maxima

它需要一个随机的x数组,并应用高斯滤波器只是为了使其平滑。这种平滑性就是为什么一旦找到一个最大值,其他最大值通常就是它的邻居。

findpeaks方法可找到分离的峰。这些峰值的位置是输出中的前两行。

中间两行是10个最大值的值。

最后两行是使用截点的最大点的位置。可以看到,您仅获得许多连续的点。

1 个答案:

答案 0 :(得分:0)

scipy.signal.find_peaks正是您要寻找的:-)
the docs开始,distance关键字确实做到了这一点-要求该峰必须比与之相距distance的所有点都高。