首页 > 解决方案 > 在numpy中找到分离的最大值

问题描述

给定一个 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]]

x 数组及其最大值

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

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

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

最后两行是使用截止点的最大点的位置。可见,您只会得到一些连续的点。

标签: pythonnumpyoptimizationscipy

解决方案


scipy.signal.find_peaks正是您正在寻找的 :-)
文档中,distance关键字正是这样做的 - 要求峰值高于所有点,直到与distance它的距离。


推荐阅读