繁体   English   中英

使用Numpy在1D numpy数组中查找超过特定阈值的最大值

[英]Finding maxima, above a certain threshold, with Numpy in a 1D numpy array

我的目标是确定当地最大值超过某个阈值的时间(以下面的日期时间格式)。 我很欣赏还有其他相关的响应,它们处理用于查找局部最大值和最小值的numpy和scipy技术,但据我所知,没有一个能够解决阈值水平。

我有以下pandas.Series,表示为df_1,它存储给定时间的整数值:

t_min
2015-12-26 14:45:00      46
2015-12-26 14:46:00      25
2015-12-26 14:47:00      39
2015-12-26 14:48:00      58
2015-12-26 14:49:00      89
2015-12-26 14:50:00      60
2015-12-26 14:51:00      57
2015-12-26 14:52:00      60
2015-12-26 14:53:00      46
2015-12-26 14:54:00      31
2015-12-26 14:55:00      66
2015-12-26 14:56:00      78
2015-12-26 14:57:00      49
2015-12-26 14:58:00      47
2015-12-26 14:59:00      31
2015-12-26 15:00:00      55
2015-12-26 15:01:00      19
2015-12-26 15:02:00      10
2015-12-26 15:03:00      31
2015-12-26 15:04:00      36
2015-12-26 15:05:00      61
2015-12-26 15:06:00      29
2015-12-26 15:07:00      32
2015-12-26 15:08:00      49
2015-12-26 15:09:00      35
2015-12-26 15:10:00      17
2015-12-26 15:11:00      22

我用下面的推断处局部最大值出现按另一种回答的响应数组索引在这里

x = np.array(df_1, dtype=np.float)

# for local maxima
print argrelextrema(x, np.greater)

但是我希望生成这些最大值出现的TIMES数组而不是这些索引处的整数(现在转换为float)值,因为我可以使用x[argrelextrema(x, np.greater)[0]] - 任何想法如何获得一系列上述时间?

继续这一点,我还旨在通过仅选择高于某个阈值的最大值 ,即其斜率高于某个极限来改进该时间列表。 这将允许我避免获得每一个局部最大值,而是识别最重要的“峰值”。 有人会建议如何做到这一点?

您可以通过获取移位的x阵列之间的差异来找到峰值:

In [14]: x
Out[14]: 
array([ 46.,  25.,  39.,  58.,  89.,  60.,  57.,  60.,  46.,  31.,  66.,
        78.,  49.,  47.,  31.,  55.,  19.,  10.,  31.,  36.,  61.,  29.,
        32.,  49.,  35.,  17.,  22.])

In [15]: x[1:] - x[:-1]
Out[15]: 
array([-21.,  14.,  19.,  31., -29.,  -3.,   3., -14., -15.,  35.,  12.,
       -29.,  -2., -16.,  24., -36.,  -9.,  21.,   5.,  25., -32.,   3.,
        17., -14., -18.,   5.])

x[1:] - x[:-1]的值给出x值之间的“斜率”。 通过选择此斜率从正变为负的位置,您可以找到原始数组中峰的索引。

In [33]: slope = x[1:] - x[:-1]

In [34]: indices = [i+1 for i in range(len(slope)-1) if slope[i] > 0 and slope[i+1] < 0]

In [35]: indices
Out[35]: [4, 7, 11, 15, 20, 23]

In [36]: [x[j] for j in indices]
Out[36]: [89, 60, 78, 55, 61, 49]

我没有费心列出时间,但是因为你对指数有所了解......

如果我理解正确,那么在使用argrelextrema之后你需要做的就是将这些索引应用于时间。 提供了您的初始代码段:

x = np.array(df_1, dtype=np.float)

# for local maxima
print argrelextrema(x, np.greater)

您需要做的就是像这样修改它:

indices = argrelextrema(x, np.greater)
df_1['time'] = df_1.index # to turn your times into a column of a dataframe - they are currently in index, right?

# So your solution is this:
print df_1.ix[indices[0], 'time']  # the [0] is there because argrelextrema returns a tuple of the array of indices and dtype, so the first item of the tuple are the indices themselves

从SciPy 1.1版开始,您还可以使用find_peaks

import numpy as np                    
import matplotlib.pyplot as plt
from scipy.signal import find_peaks 

x = np.array([ 46.,  25.,  39.,  58.,  89.,  60.,  57.,  60.,  46.,  31.,  66.,
        78.,  49.,  47.,  31.,  55.,  19.,  10.,  31.,  36.,  61.,  29.,
        32.,  49.,  35.,  17.,  22.])

peaks, _ = find_peaks(x)

plt.plot(x)
plt.plot(peaks, x[peaks], "x")
plt.show()

这将绘制将获得所有局部最大值:

在此输入图像描述

如果您现在想要使用阈值(例如60),则可以使用(其余代码相同):

peaks, _ = find_peaks(x, height=60)

这将绘制:

在此输入图像描述

暂无
暂无

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

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