简体   繁体   English

计算python中的直方图峰值

[英]calculate histogram peaks in python

In Python, how do I calcuate the peaks of a histogram?在 Python 中,如何计算直方图的峰值?

I tried this:我试过这个:

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)

But the result was:但结果是:

(array([3]),)

I'd expect it to find the peaks in bin 0 and bin 3.我希望它能在 bin 0 和 bin 3 中找到峰值。

Note that the peaks span more than 1 bin.请注意,峰值跨度超过 1 个区间。 I don't want it to consider the peaks that span more than 1 column as additional peak.我不希望它将跨越 1 列以上的峰视为附加峰。

I'm open to another way to get the peaks.我愿意接受另一种方式来获得峰值。

Note:笔记:

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

In computational topology, the formalism of persistent homology provides a definition of "peak" that seems to address your need.在计算拓扑中,持久同源性的形式提供了“峰值”的定义,似乎可以满足您的需求。 In the 1-dimensional case the peaks are illustrated by the blue bars in the following figure:在一维情况下,峰值由下图中的蓝条表示:

最持久的峰值

A description of the algorithm is given in this Stack Overflow answer of a peak detection question .该算法的描述在峰值检测问题的堆栈溢出答案中给出。

The nice thing is that this method not only identifies the peaks but it quantifies the "significance" in a natural way.好消息是这种方法不仅可以识别峰值,而且可以以自然的方式量化“重要性”。

A simple and efficient implementation (as fast as sorting numbers) and the source material to the above answer given in this blog article: https://www.sthu.org/blog/13-perstopology-peakdetection/index.html一个简单有效的实现(与排序数字一样快)以及本博客文章中给出的上述答案的源材料: https : //www.sthu.org/blog/13-perstopology-peakdetection/index.html

I wrote an easy function:我写了一个简单的函数:

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

I defined a peak as a value bigger than 180% that of the neighbors and bigger than 5% of the max value.我将峰值定义为大于相邻值的 180% 且大于最大值的 5% 的值。 Of course you can adapt the values as you prefer in order to find the best set up for your problem.当然,您可以根据自己的喜好调整这些值,以便为您的问题找到最佳设置。

Try the findpeaks library.试试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']

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM