Ich habe Zeitreihendaten. Daten generieren
date_rng = pd.date_range('2019-01-01', freq='s', periods=400)
df = pd.DataFrame(np.random.lognormal(.005, .5,size=(len(date_rng), 3)),
columns=['data1', 'data2', 'data3'],
index= date_rng)
s = df['data1']
Ich möchte eine Zick-Zack-Linie zwischen den lokalen Maxima und den lokalen Minima erstellen, die die Bedingung erfüllt, dass auf der y-Achse |highest - lowest value|
jeder Zick-Zack-Linie einen Prozentsatz (z. B. 20%) des Abstands der vorherigen überschreiten muss Zick-Zack-Linie UND ein vorgegebener Wert k (sagen wir 1,2)
Ich kann die lokalen Extrema mit diesem Code finden:
# Find peaks(max).
peak_indexes = signal.argrelextrema(s.values, np.greater)
peak_indexes = peak_indexes[0]
# Find valleys(min).
valley_indexes = signal.argrelextrema(s.values, np.less)
valley_indexes = valley_indexes[0]
# Merge peaks and valleys data points using pandas.
df_peaks = pd.DataFrame({'date': s.index[peak_indexes], 'zigzag_y': s[peak_indexes]})
df_valleys = pd.DataFrame({'date': s.index[valley_indexes], 'zigzag_y': s[valley_indexes]})
df_peaks_valleys = pd.concat([df_peaks, df_valleys], axis=0, ignore_index=True, sort=True)
# Sort peak and valley datapoints by date.
df_peaks_valleys = df_peaks_valleys.sort_values(by=['date'])
aber ich weiß nicht, wie ich die Schwellenbedingung darauf anwenden soll. Bitte teilen Sie mir mit, wie diese Bedingung anzuwenden ist.
Da die Daten Millionen Zeitstempel enthalten können, wird eine effiziente Berechnung dringend empfohlen
Für eine klarere Beschreibung:
Beispielausgabe meiner Daten:
# Instantiate axes.
(fig, ax) = plt.subplots()
# Plot zigzag trendline.
ax.plot(df_peaks_valleys['date'].values, df_peaks_valleys['zigzag_y'].values,
color='red', label="Zigzag")
# Plot original line.
ax.plot(s.index, s, linestyle='dashed', color='black', label="Org. line", linewidth=1)
# Format time.
ax.xaxis_date()
ax.xaxis.set_major_formatter(mdates.DateFormatter("%Y-%m-%d"))
plt.gcf().autofmt_xdate() # Beautify the x-labels
plt.autoscale(tight=True)
plt.legend(loc='best')
plt.grid(True, linestyle='dashed')
Meine gewünschte Ausgabe (etwas Ähnliches, der Zickzack verbindet nur die signifikanten Segmente)