首页 > 解决方案 > numpy怎么办?...在 numpy 语法中找到“突出”计算的峰值

问题描述

对 numpy 用户来说有点陌生,试图查看“如何使用 numpy”解决算法中的 numpy 语法问题。

我希望在这里寻求帮助是可以的,因为我很困惑并且希望得到一些建议 - 我希望这不是 TLDR'ish !

背景

我正在尝试手动计算“突出”以从寻峰中移除峰值,并尝试查看是否有一种简单的“numpy”方法来做到这一点,而不是 for 循环。

在任何人说之前,我知道scipy.find_peaks可以删除具有指定突出度的峰值,但我试图弄清楚如何 使用 numpy 语法手动完成它,而不是循环索引(我知道 C,我正在尝试学习麻木...):


原因

原因是我需要将现有的 scipy 逻辑从“如果峰值左侧或右侧的突出度都可以(即足够大),那么峰值应该保留”更改为“如果左侧或右侧突出度太小,然后删除峰值”

这相当于将scipy 代码第 252 行的代码max(left_min, right_min)更改为min(left_min, right_min)


_peak_prominences用于查找突出值的 scipy代码在数组上使用 for 循环向前/向后循环 -我试图了解这是否可能是 numpy 表示法/语法(没有 for 循环),但经过一天的努力,无法弄清楚如何这样做 - 所以会喜欢一些麻木的建议!


概念逻辑很简单:在剖面(1d 数组)中找到峰,然后计算每个峰在左/右相邻谷上的高度(即“突出”),然后移除左或右高度小于的峰一定的门槛 - 即它们在双方都不够“尖峰” 。

在此处输入图像描述


在上面的示例中,我想删除两个中心峰,因为两者在中央“山谷”上方的高度(突出)太小 - 即使周围的两个外部山谷高度都可以。


所以,我的 numpy 帮助问题

我知道如果我有一个peaks数组是数组的索引profile,我可以使用 np.delete 删除“峰值不够高”,如果我可以计算每个峰值的 left_height 和 right_height 数组集:

np.delete(peaks, np.where( (left_height<10) | (right_height<10) )[0])

我知道对于 peaks 数组中的特定值,我可以通过在峰值索引之间切片并在切片中找到最小轮廓值来找到它们之间的“谷”:

profile[peaks[0]:peaks[1]].min()

我想不通的是如何在 numpy 方面计算 left_height 和 right_height 数组。 就像是

left_height = profile[peaks] - profile[peaks[-1]:peaks].min()

这本质上是“使用具有当前和先前位置的峰值数组来制作切片,然后使用该切片获取配置文件值,然后计算这些配置文件值的最小值的逻辑。

仅使用 python-istic numpy 是否可以实现这种逻辑,还是需要手动 for 循环?

标签: python-3.xnumpyscipy

解决方案


这是一个很好的学习方式!:)

的第一个版本peak_prominences实际上是作为纯 Python 实现添加的,您可以在此处找到。

该实现仍然在每个峰值上循环一次,并且显然比 Cython 实现慢,但可能仍然是您正在寻找的。正如您已经建议的那样,您基本上想要更改在403 和 404 行上计算轮廓高度的方式。

我想不通的是如何在 numpy 方面计算 left_height 和 right_height 数组。就像是

left_height = profile[peaks] - profile[peaks[-1]:peaks].min()

您似乎已经非常接近第 382 到 400 行的解决方案,其中计算了左右高度(之前忽略了与窗口相关的内容)。peak这是使用您的变量名找到单个的左右高度的关键位:

# Positions where profile is larger than current peak height
greater_peak = np.where(profile > profile[peak])[0]

try:
    # Nearest position to the left of peak with
    # profile[left] > profile[peak]
    left = greater_peak[greater_peak < peak].max()
except ValueError:
    left = 0
try:
    # Nearest position to right of peak with
    # profile[right] > profile[peak]
    right = greater_peak[greater_peak > peak].min()
except ValueError:
    right = None

# Base indices to the left and right of peak in profile
left_height = profile[left:peak].argmin() + left
right_height = profile[peak:right].argmin() + peak

我希望这对您的努力有所帮助。

免责声明:我是该功能的作者。


推荐阅读