Python-基于相对高度过滤局部极值

Python-基于相对高度过滤局部极值,python,pandas,numpy,dataframe,Python,Pandas,Numpy,Dataframe,使用,很容易找到数据帧列的局部极值: import numpy as np import matplotlib.pyplot as plt import pandas as pd # Generate a noisy AR(1) sample np.random.seed(0) rs = np.random.randn(200) xs = [0] for r in rs: xs.append(xs[-1]*0.9 + r) df = pd.DataFrame(xs, columns=[

使用,很容易找到数据帧列的局部极值:

import numpy as np
import matplotlib.pyplot as plt
import pandas as pd

# Generate a noisy AR(1) sample
np.random.seed(0)
rs = np.random.randn(200)
xs = [0]
for r in rs:
    xs.append(xs[-1]*0.9 + r)
df = pd.DataFrame(xs, columns=['data'])

# Find local peaks
df['min'] = df.data[(df.data.shift(1) > df.data) & (df.data.shift(-1) > df.data)]
df['max'] = df.data[(df.data.shift(1) < df.data) & (df.data.shift(-1) < df.data)]

# Plot results
plt.scatter(df.index, df['min'], c='r')
plt.scatter(df.index, df['max'], c='g')
df.data.plot()
它给出了以下图表:

现在,我想将这些极值成对分组,最小和极值是相邻的,按照这个顺序,并移除极值<最小+阈值的对。通过删除,我的意思是用nans替换df['min']和df['max']中的相应值。 这基本上过滤了不相关的小极值。 我尝试过用不同的选项来寻找_峰,但没有一个给出预期的结果


有没有一种优雅而快速的方法可以做到这一点?

我想你错过了这里报道的Foad的精彩答案

您可以设置邻居的窗口数并查找值的局部最小值和最大值,而不是按1的移位计算最大值和最小值。虽然没有一个窗口参数可以完美匹配,但它大大降低了噪音

from scipy.signal import argrelextrema

# Find peaks in the window
n = 10 #window size
df['min'] = df.iloc[argrelextrema(df.data.values, np.less_equal, order=n)[0]]['data']
df['max'] = df.iloc[argrelextrema(df.data.values, np.greater_equal, order=n)[0]]['data']

我想你错过了这里报道的Foad的精彩答案

您可以设置邻居的窗口数并查找值的局部最小值和最大值,而不是按1的移位计算最大值和最小值。虽然没有一个窗口参数可以完美匹配,但它大大降低了噪音

from scipy.signal import argrelextrema

# Find peaks in the window
n = 10 #window size
df['min'] = df.iloc[argrelextrema(df.data.values, np.less_equal, order=n)[0]]['data']
df['max'] = df.iloc[argrelextrema(df.data.values, np.greater_equal, order=n)[0]]['data']

我同意前面的说法,但我认为这可能更符合你的要求

threshold = 0.8
points = df.dropna(subset=['min', 'max'], how='all').copy()
ddf = pd.merge(points['min'].dropna().reset_index(),
               points['max'].dropna().reset_index(),
               left_index=True,
               right_index=True)
ddf = ddf[ddf['max'] < (ddf['min'] + threshold)]

# Plot results
plt.scatter(ddf['index_x'], ddf['min'], c='r')
plt.scatter(ddf['index_y'], ddf['max'], c='g')
df.data.plot()
要将其合并回原始数据帧,请执行以下操作:

df['min'] = df.index.map(ddf.set_index('index_x')['min'])
df['max'] = df.index.map(ddf.set_index('index_y')['max'])

我同意前面的说法,但我认为这可能更符合你的要求

threshold = 0.8
points = df.dropna(subset=['min', 'max'], how='all').copy()
ddf = pd.merge(points['min'].dropna().reset_index(),
               points['max'].dropna().reset_index(),
               left_index=True,
               right_index=True)
ddf = ddf[ddf['max'] < (ddf['min'] + threshold)]

# Plot results
plt.scatter(ddf['index_x'], ddf['min'], c='r')
plt.scatter(ddf['index_y'], ddf['max'], c='g')
df.data.plot()
要将其合并回原始数据帧,请执行以下操作:

df['min'] = df.index.map(ddf.set_index('index_x')['min'])
df['max'] = df.index.map(ddf.set_index('index_y')['max'])

如何平滑曲线并在曲线上找到局部最小值和最大值?这是一种选择吗?或者Foad的答案是,如何平滑曲线,并在曲线上找到局部最小值和最大值?这是一种选择吗?或者Foad的回答谢谢你的回复,我确实看到了Foad的回答,但这并不完全是我需要的。基本上,我需要一分钟,一分钟,一分钟。。。当移除垂直太近的最小、最大对,而不是水平的对来回答时,我确实看到了Foad的答案,但这并不完全是我需要的。基本上,我需要一分钟,一分钟,一分钟。。。当移除垂直距离太近而不是水平距离太近的最小、最大对时,这确实起到了作用!您将如何用存储在ddf['max']和ddf['min']中的过滤值替换df中未过滤的df['min']和df['max']值?非常感谢,这真的很管用!如何用存储在ddf['max']和ddf['min']中的过滤值替换df中未过滤的df['min']和df['max']值?