How can the smaller maxima and the larger minima between a respective maxima / minima be removed? I always want a maximum to follow a minimum or vice versa a minimum to follow a maximum.
import numpy as np
import matplotlib.pyplot as plt
import pandas as pd
from scipy.signal import argrelextrema
# 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'])
n = 5 # number of points to be checked before and after
# Find local peaks
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']
# Plot results
plt.scatter(df.index, df['min'], c='r')
plt.scatter(df.index, df['max'], c='g')
plt.plot(df.index, df['data'])
plt.show()
CodePudding user response:
You can do something like that. We group df into parts between successive maxima and then for each part take only the smallest min. Then we group by min and take the highest max only for each part:
max_grouper = (~df['max'].isna()).cumsum()
df['min2'] = (df.groupby(max_grouper, group_keys = False)
.apply (lambda g: g['min'].where(g['min'] == g['min'].min()))
)
min_grouper = (~df['min2'].isna()).cumsum()
df['max2'] = (df.groupby(min_grouper, group_keys = False)
.apply (lambda g: g['max'].where(g['max'] == g['max'].max()))
)
I put the "pruned" min and max into 'min2' and 'max2' columns. We plot them using yellow and blue, while keeping the original red and greens:
plt.scatter(df.index, df['min'], c='r')
plt.scatter(df.index, df['max'], c='g')
plt.scatter(df.index, df['min2'], c='y')
plt.scatter(df.index, df['max2'], c='b')
plt.plot(df.index, df['data'])
plt.show()
output:
The red ones are the ones that do not exist in 'min2'. In this case no 'max' points were removed