在Python中,如何计算直方图的峰值?
我试过了:
import numpy as np
from scipy.signal import argrelextrema
data = [0, 1, 2, 3, 4, 0, 1, 2, 3, 4, 0, 1, 2, 3, 4, 1, 2, 3, 4,
5, 6, 7, 8, 9, 5, 6, 7, 8, 9, 5, 6, 7, 8, 9,
12,
15, 16, 17, 18, 19, 15, 16, 17, 18,
19, 20, 21, 22, 23, 24,]
h = np.histogram(data, bins=[0, 5, 10, 15, 20, 25])
hData = h[0]
peaks = argrelextrema(hData, np.greater)
但结果是:
(array([3]),)
我希望它能找到bin 0和bin 3中的峰值。
请注意,峰值跨度超过1个bin。我不希望它将超过1列的峰视为额外的峰值。
我可以通过另一种方式获得高峰。
注意:
>>> h[0]
array([19, 15, 1, 10, 5])
>>>
答案 0 :(得分:4)
在计算拓扑中,持久同源的形式主义提供了“峰值”的定义,似乎可以满足您的需求。在一维情况下,峰值由下图中的蓝色条表示:
在此给出了算法的描述 Stack Overflow answer的peak detection question。
不错的是,这种方法不仅可以识别峰值,还可以自然地量化“重要性”。
一个简单而有效的实现(与排序数字一样快)和本博客文章中给出的上述答案的源材料: https://www.sthu.org/blog/13-perstopology-peakdetection/index.html
答案 1 :(得分:2)
尝试使用findpeaks
库。
pip install findpeaks
# Your input data:
data = [0, 1, 2, 3, 4, 0, 1, 2, 3, 4, 0, 1, 2, 3, 4, 1, 2, 3, 4, 5, 6, 7, 8, 9, 5, 6, 7, 8, 9, 5, 6, 7, 8, 9, 12, 15, 16, 17, 18, 19, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,]
# import library
from findpeaks import findpeaks
# Find some peaks using the smoothing parameter.
fp = findpeaks(lookahead=1, interpolate=10)
# fit
results = fp.fit(data)
# Make plot
fp.plot()
# Results with respect to original input data.
results['df']
# Results based on interpolated smoothed data.
results['df_interp']
答案 2 :(得分:1)
我写了一个简单的功能:
def find_peaks(a):
x = np.array(a)
max = np.max(x)
lenght = len(a)
ret = []
for i in range(lenght):
ispeak = True
if i-1 > 0:
ispeak &= (x[i] > 1.8 * x[i-1])
if i+1 < lenght:
ispeak &= (x[i] > 1.8 * x[i+1])
ispeak &= (x[i] > 0.05 * max)
if ispeak:
ret.append(i)
return ret
我将峰值定义为大于邻居的180%的值,并且大于最大值的5%。当然,您可以根据需要调整值,以便找到最适合您问题的设置。