繁体   English   中英

如何在 python 中的 0 点之间找到时间序列数据的最高峰?

[英]How to find highest peaks in time series data between points of 0 in python?

我正在尝试获取我的时间序列数据并隔离 0 点之间的所有数据,然后识别具有最高峰值的那些区间。 我在 python 工作。

参考此图:确定了峰值和谷值的时间序列数据

资料来源: https://tcoil.info/find-peaks-and-valleys-in-dataset-with-python/

注意到第一个和最后一个红谷点都在 0,我想找到一种方法来获取时间序列数据,识别 y 轴上 0 处的所有点,然后隔离其间的数据。 对于我在此处链接的图表,我想隔离第一个和最后一个红谷点之间的所有数据。 我想在整个时间序列数据集中执行此操作,其中 y 轴上 0 点之间的数据是隔离的。 现在这些间隔是孤立的(代表整个数据中的不同事件/周期),我想记录每个间隔内的最高点。 然后我想找到具有 5 个最高峰的区间(每个区间一个峰)。 最后,我想 output 包含这些前 5 个峰值的区间(或范围)。 对于上下文,这些间隔中的每一个都代表一个事件/周期,我想找到最极端的。 因此,我想要一个 output 基本上告诉我最极端的事件/周期发生在 2020 年 3 月 5 日到 2020 年 3 月 24 日之间。

如何在 python 中做到这一点? 我需要先平滑数据吗? 我将如何 go 关于隔离 y 轴上 0 点之间的数据? 我想首先弄清楚 go 的哪个方向,但还没有代码。

让我们使用您引用的数据。 我将添加详细的解释作为评论。

x = np.linspace(-1, 3, 1000)
y = -0.1 * np.cos(12*x) + np.exp(-(1-x)**2)

我想找到一种方法来获取时间序列数据,识别 y 轴上 0 处的所有点,然后隔离介于两者之间的数据

所以基本上你想分开y轴上方和y轴下方的连续点。 基于此答案,您可以执行以下操作:

fig, ax = plt.subplots(figsize=(10, 5))
ax.plot(x, y, color='black')    

# Find all consecutive chunks that are above y=0
for start, stop in contiguous_regions(y > 0):
    ax.plot(x[start:stop], y[start:stop], color='red')

# Find all consecutive chunks that are below y=0
for start, stop in contiguous_regions(y < 0):
    ax.plot(x[start:stop], y[start:stop], color='blue')

ax.axhline(0, color='grey')
plt.show()
plt.close()

如您所见,蓝点位于 y 轴下方,红点位于上方。 他们肯定是孤立的。

在此处输入图像描述

对于我在此处链接的图表,我想隔离第一个和最后一个红谷点之间的所有数据。

你也可以这样做。 对于每一块,我们需要找到它的山谷,您可以通过查看您发送给我们的链接来完成!

fig, ax = plt.subplots(figsize=(10, 5))
ax.plot(x, y, color='black')    
for start, stop in contiguous_regions(y > 0):
    x_chunk, y_chunk = x[start:stop], y[start:stop] 
    ax.plot(x_chunk, y_chunk, color='red')
    
    # Find all the valleys
    valleys = (np.diff(np.sign(np.diff(y_chunk))) > 0).nonzero()[0] + 1
    
    # If there's more than two valleys (the first and the last)
    if valleys.size > 2:
        # Get'em!
        iv0, *_, iv1 = valleys
        
        # Plot'em!
        ax.plot(x_chunk[iv0:iv1], y_chunk[iv0:iv1], color='red', linewidth=4)
    
for start, stop in contiguous_regions(y < 0):
    x_chunk, y_chunk = x[start:stop], y[start:stop] 
    ax.plot(x_chunk, y_chunk, color='blue')
    
    # The same.
    valleys = (np.diff(np.sign(np.diff(y_chunk))) > 0).nonzero()[0] + 1
    if valleys.size > 2:
        iv0, *_, iv1 = valleys
        ax.plot(x_chunk[iv0:iv1], y_chunk[iv0:iv1], color='blue', linewidth=4)
        
ax.axhline(0, color='grey')
plt.show()
plt.close()

看到那条大红线了吗? 这是我们的,没错。

在此处输入图像描述

我们开始在这里重复自己。 让我们做一个 function:

def do_chunk(x_chunk, y_chunk, color):
    ax.plot(x_chunk, y_chunk, color=color)
    
    valleys = (np.diff(np.sign(np.diff(y_chunk))) > 0).nonzero()[0] + 1
    if valleys.size > 2:
        iv0, *_, iv1 = valleys
        ax.plot(x_chunk[iv0:iv1], y_chunk[iv0:iv1], color=color, linewidth=4)

fig, ax = plt.subplots(figsize=(10, 5))
ax.plot(x, y, color='black')    
for start, stop in contiguous_regions(y > 0):
    do_chunk(x[start:stop], y[start:stop], 'red')
    
for start, stop in contiguous_regions(y < 0):
    do_chunk(x[start:stop], y[start:stop], 'blue')
    
ax.axhline(0, color='grey')
plt.show()
plt.close()

这更好,甚至更好:使用相同的 plot。 下一步是什么?

现在这些间隔是孤立的(代表整个数据中的不同事件/周期),我想记录每个间隔内的最高点。

但这太容易了。 让我们像裘德一样,他可能做到了

def do_chunk(x_chunk, y_chunk, color):
    ax.plot(x_chunk, y_chunk, color=color)
    
    valleys = (np.diff(np.sign(np.diff(y_chunk))) > 0).nonzero()[0] + 1
    if valleys.size > 2:
        iv0, *_, iv1 = valleys
        x_trim, y_trim = x_chunk[iv0:iv1], y_chunk[iv0:iv1]
        ax.plot(x_trim, y_trim, color=color, linewidth=4)
        
        # Get the index of the maximum value in this trim
        ip = np.argmax(y_trim)
        ax.scatter(x_trim[ip], y_trim[ip], color='blue')

fig, ax = plt.subplots(figsize=(10, 5))
ax.plot(x, y, color='black')    
for start, stop in contiguous_regions(y > 0):
    do_chunk(x[start:stop], y[start:stop], 'red')
    
for start, stop in contiguous_regions(y < 0):
    do_chunk(x[start:stop], y[start:stop], 'blue')
    
ax.axhline(0, color='grey')
plt.show()
plt.close()

你看到那边那个小点了吗? 它也是我们的。 最大峰值。

在此处输入图像描述

然后我想找到具有 5 个最高峰的区间(每个区间一个峰)

好吧,这是一个更难的。 让我们创建一些列表,以便我们可以存储它们!

def do_chunk(x_chunk, y_chunk, color):
    ax.plot(x_chunk, y_chunk, color=color)
    
    valleys = (np.diff(np.sign(np.diff(y_chunk))) > 0).nonzero()[0] + 1
    if valleys.size > 2:
        iv0, *_, iv1 = valleys
        x_trim, y_trim = x_chunk[iv0:iv1], y_chunk[iv0:iv1]
        ax.plot(x_trim, y_trim, color=color, linewidth=4)
        
        ip = np.argmax(y_trim)
        ax.scatter(x_trim[ip], y_trim[ip], color='blue')
        
        # Return the x, y of the peak
        return x_trim[ip], y_trim[ip]
    
    return None

fig, ax = plt.subplots(figsize=(10, 5))
ax.plot(x, y, color='black')    

intervals = []

for start, stop in contiguous_regions(y > 0):
    # Receive it here
    peak = do_chunk(x[start:stop], y[start:stop], 'red')
    
    # If this data contains at least two valleys
    if peak is not None:
        # Let's use a Javascript favorite to store data: JSONs
        intervals.append({
            'start': start,
            'stop': stop,
            'peak': peak,
        })
    
for start, stop in contiguous_regions(y < 0):
    peak = do_chunk(x[start:stop], y[start:stop], 'blue')
    if peak is not None:
        intervals.append({
            'start': start,
            'stop': stop,
            'peak': peak,
        })
    
ax.axhline(0, color='grey')
plt.show()
plt.close()

那么, intervals内是什么? 让我们看看,哦。 我已经检查过这里。 它在给

[{'start': 121, 'stop': 892, 'peak': (0.8098098098098099, 1.0602140027371494)}]

这甚至意味着什么? 这意味着,从索引121到索引892 ,找到的最高峰位于 x=0.809 和 y=1.060。 太好了,是吗? 由于正在使用的数据只包含一个峰值,那就是他。

要找到最高的 y 峰,只需执行列表推导:

# High five!
high_five = sorted(  # Sort it, so the highest peaks will be on the list tail
    [(interval["start"], interval["stop"]) for interval in intervals],
    key=lambda interval: interval["peak"][1], # Filter by the y-value of its peak
)[:-5]  # Get the last five

最后,我想 output 包含这些前 5 个峰值的区间(或范围)。

现在很容易,但我会把这个留给你。 相信我,最糟糕的部分已经完成。

暂无
暂无

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

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