python - 在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
数组,并应用高斯滤波器以使其平滑。这种平滑性就是为什么一旦你找到一个最大值,其他的通常就是它的邻居。
该findpeaks
方法找到分离的峰。这些峰值的位置是输出中的前两行。
中间两行是 10 个最大值的值。
最后两行是使用截止点的最大点的位置。可见,您只会得到一些连续的点。
解决方案
scipy.signal.find_peaks
正是您正在寻找的 :-)
从文档中,distance
关键字正是这样做的 - 要求峰值高于所有点,直到与distance
它的距离。
推荐阅读
- postgresql - 如何使用验证批量导入并使用 paper_trail 创建版本?
- javascript - JavaScript中从当前日期到分钟的时间差
- javascript - 移动响应式菜单放置
- postgresql - 具有 UNIQUE 约束的重复记录
- amazon-web-services - 如何使用不同的环境变量在 AWS ECS 上安排多个任务?
- ansible - 如何根据变量中定义的主机名在多个主机中执行任务
- spring-webflux - Spring Webflux 使用 DataBuffer 将 WebClient.exchange() 迁移到 WebClient.exchangeToMono()
- mechanicalturk - 创建包含 Mturk“workerId”但在 Turkprime(Cloudresearch)中称为“participant_label”的外部链接
- python - 连续说出 nsfw 单词 3 次后如何使不和谐机器人静音用户
- c# - 谁在显示 ContextMenu:表单还是通知图标?