我的目标是确定当地最大高于某个阈值的时间(以下面的日期时间格式)。我很欣赏还有其他相关的回应,它们涉及找到局部最大值和最小值的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
我使用以下内容推断出根据另一个答案here中的响应发生局部最大值的数组索引:
x = np.array(df_1, dtype=np.float)
# for local maxima
print argrelextrema(x, np.greater)
但是我希望生成这些最大值出现的TIMES数组而不是这些索引的整数(现在转换为float)值,正如我在x[argrelextrema(x, np.greater)[0]]
找到的那样 - 任何想法如何获得所述时间的数组?
继续这一点,我还打算通过仅选择超过某个阈值的最大值来改进这个时间列表,即其斜率高于某个限制。这将允许我避免获得每一个局部最大值,而是识别最重要的“峰值”。有人会建议如何做到这一点吗?
答案 0 :(得分:2)
您可以通过获取移位的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]
我没有费心列出时间清单,但是因为你对指数有所了解......
答案 1 :(得分:0)
如果我理解正确,您在使用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
答案 2 :(得分:0)
从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)
这将绘图: