计算python中的直方图峰值

calculate histogram peaks in python

在Python中,如何计算柱状图的峰值?

我试过这个:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
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)

但结果是:

1
(array([3]),)

我希望它能在0号箱和3号箱找到峰值。

请注意,峰值跨度超过1个箱。我不想把跨度超过1列的峰当作附加峰。

我愿意用另一种方法来达到顶峰。

注:

1
2
3
>>> h[0]
array([19, 15,  1, 10,  5])
>>>


在计算拓扑中,持久同调的形式主义提供了"峰值"的定义,似乎可以满足您的需求。在一维情况下,峰值由下图中的蓝色条表示:

Most persistent peaks

本文给出了算法的描述。峰值检测问题的堆栈溢出答案。

好的是,这种方法不仅能识别峰,而且能自然地量化"意义"。

一个简单而有效的实现(与数字排序一样快)以及本博客文章给出的上述答案的源材料:https://www.sthu.org/blog/13-perspotology-peakdetection/index.html


我写了一个简单的函数:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
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%的值。当然,您可以根据自己的喜好调整这些值,以便为您的问题找到最佳设置。