Taking derivatives:
df['increasing'] = df.data.diff()
df['decreasing'] = df.data.diff(-1)
df['local_max'] = ((df.increasing>0) & (df.decreasing>0))
df['local_min'] = ((df.increasing<0) & (df.decreasing<0))
Result
data increasing decreasing local_max local_min
0 1.0 NaN -1.0 False False
1 2.0 1.0 -1.0 False False
2 3.0 1.0 -1.0 False False
3 4.0 1.0 0.5 True False
4 3.5 -0.5 1.0 False False
5 2.5 -1.0 1.0 False False
6 1.5 -1.0 -0.5 False True
7 2.0 0.5 -0.4 False False
8 2.4 0.4 -1.1 False False
9 3.5 1.1 NaN False False
This is a solution with pandas as you requested
CodePudding user response:
One way using scipy.signal.find_peaks. Since it cannot detect a maxima at the either end of an array, use numpy.pad as well:
import numpy as np
from scipy.signal import find_peaks
import matplotlib.pyplot as plt
s = df["battery_percentage"]
maxima, _ = find_peaks(np.pad(s, 1))
maxima -= 1 # This is to revert the changed indices from padding above
Since find_peaks can only detect local maxima, we reverse original array, shift it up by global maximum, then pad:
minima, _ = find_peaks(np.pad(-s s.max(), 1))
minima -= 1
Visualize result using matplotlib:
s.plot(figsize=(20, 10))
plt.scatter(maxima, s[maxima], s=1000, facecolors='none', edgecolors='g')
plt.scatter(minima, s[minima], s=1000, facecolors='none', edgecolors='r')
Plot:


