diff --git a/spike_finder/src/spike_finder/core.py b/spike_finder/src/spike_finder/core.py new file mode 100644 index 0000000..c68523b --- /dev/null +++ b/spike_finder/src/spike_finder/core.py @@ -0,0 +1,49 @@ +import pandas as pd +from datetime import datetime +from typing import List, Dict, Any + + +def find_spikes(log_data: List[Dict[str, Any]], threshold: float) -> List[Dict[str, Any]]: + """Analysiert Logdaten, um Spike-Events zu finden, deren Werte den Schwellenwert überschreiten. + + Args: + log_data: Liste von Logeinträgen mit mindestens 'timestamp' und 'value'. + threshold: Grenzwert, oberhalb dessen ein Wert als Spike gilt. + + Returns: + Liste von SpikeEvents (Dictionaries) mit Zeitpunkt, Wert und Kontextfenster. + """ + if not isinstance(log_data, list): + raise ValueError("log_data muss eine Liste von Dictionaries sein.") + if not all(isinstance(entry, dict) for entry in log_data): + raise ValueError("Jeder Logeintrag muss ein Dictionary sein.") + + if not log_data: + return [] + + df = pd.DataFrame(log_data) + if 'timestamp' not in df.columns or 'value' not in df.columns: + raise ValueError("Erwartete Felder 'timestamp' und 'value' fehlen in den Logdaten.") + + # Konvertiere Zeitstempel in datetime + df['timestamp'] = pd.to_datetime(df['timestamp'], errors='coerce') + df = df.dropna(subset=['timestamp', 'value']) + + if df.empty: + return [] + + spikes = [] + window_size = 2 # Kontextfenster: 2 Werte davor und danach + for i, row in df.iterrows(): + if float(row['value']) > threshold: + start = max(0, i - window_size) + end = min(len(df), i + window_size + 1) + context_values = df.iloc[start:end]['value'].tolist() + spike_event = { + 'timestamp': row['timestamp'].isoformat(), + 'value': float(row['value']), + 'context_window': [float(v) for v in context_values] + } + spikes.append(spike_event) + + return spikes \ No newline at end of file