HOWTO · Python
Kreuzkorrelation in Python
In diesem Artikel werden mehrere Möglichkeiten zur Verarbeitung der Kreuzkorrelation in Python erörtert.
Auf dieser Seite
Die Kreuzkorrelation vergleicht zwei numerische Folgen reeller Werte, indem eine Folge relativ zur anderen verschoben wird. Für jede relative Position ergibt sich ein Wert, der zeigt, wo sich Muster ähneln. Standardmäßig sind diese Werte Summen von Produkten; sie sind nicht automatisch normalisierte Korrelationskoeffizienten.
Was die Kreuzkorrelation misst
Bei Folgen reeller Werte x und y multipliziert die Kreuzkorrelation die jeweils überlappenden Werte und summiert die Produkte für jede Verschiebung. Ein hoher positiver Wert bedeutet, dass die Werte bei dieser Verschiebung tendenziell dasselbe Vorzeichen und Muster aufweisen; ein negativer Wert deutet auf entgegengesetzte Vorzeichen hin. Der Wert hängt außerdem von der Skalierung der Folgen und der Anzahl überlappender Werte ab.
Der Modus full umfasst jede Verschiebung mit mindestens einem überlappenden Wertepaar. Hat x die Länge N und y die Länge M, entstehen dabei N + M - 1 Werte. Der Modus valid berücksichtigt nur Verschiebungen, bei denen die kürzere Folge vollständig innerhalb der längeren liegt. Der Modus same liefert ein Ergebnis, das auf die erste Eingabe zentriert ist und deren Länge hat; bei geraden Längen hängt die genaue Zentrierung von der Bibliothek ab. Diese Modi legen fest, welche Verschiebungen einbezogen werden, nicht die Normalisierung.
Kreuzkorrelation mit reinem Python berechnen
Eine direkte Implementierung macht die Überlappung und die Lag-Konvention deutlich. Für Folgen reeller Werte x und y liefert der folgende Code nicht normalisierte Summen überlappender Produkte. Reihenfolge der Lags und Ergebnisse entsprechen bei reellen Eingaben der Konvention von NumPys correlate(x, y, mode="full").
Führen Sie dieses Beispiel aus:
Der Code und die angezeigten Bezeichnungen oder Ausgaben in diesem Abschnitt bleiben auf Englisch.
x = [1, 2, 3]
y = [4, 5]
scores = []
for lag in range(-len(y) + 1, len(x)):
score = sum(
x[index + lag] * y[index]
for index in range(len(y))
if 0 <= index + lag < len(x)
)
scores.append(score)
print(scores)
[5, 14, 23, 12]
Die Folge enthält einen Wert pro Lag; die Reihenfolge reicht von -(len(y) - 1) bis len(x) - 1. Jeder Wert berücksichtigt nur überlappende Indexpaare. Diese einfache Methode eignet sich für kleine Eingaben und zum Verständnis der Berechnung; der Aufwand der verschachtelten Schleifen wächst mit dem Produkt der Folgenlängen.
NumPy für die Kreuzkorrelation verwenden
Installieren Sie NumPy mit python -m pip install numpy. numpy.correlate verarbeitet eindimensionale numerische Arrays reeller Werte und bietet die Modi full, same und valid. Standardmäßig gilt valid. Geben Sie daher einen Modus an, wenn Sie eine bestimmte Auswahl an Verschiebungen benötigen.
Der Code und die angezeigten Bezeichnungen oder Ausgaben in diesem Abschnitt bleiben auf Englisch.
import numpy as np
x = np.array([1, 2, 3])
y = np.array([4, 5])
scores = np.correlate(x, y, mode="full")
print(scores.tolist())
[5, 14, 23, 12]
Bei diesen reellen Eingaben stimmen die Reihenfolge der Lags im Modus full und die nicht normalisierten Produktsummen mit dem Beispiel in reinem Python überein. NumPy konjugiert bei komplexen Daten die zweite Eingabe; der obige Python-Code tut das nicht. Die Übereinstimmung gilt daher nur für reelle Eingaben. Wandeln Sie Arrays nur dann in Listen um, wenn eine einfache Python-Darstellung nützlich ist; für weitere numerische Berechnungen sind NumPy-Arrays meist praktischer. Für diesen Vergleich sollten die Eingaben reell und eindimensional sein.
SciPy für die Kreuzkorrelation verwenden
Installieren Sie SciPy mit python -m pip install scipy; SciPy benötigt außerdem NumPy. scipy.signal.correlate bietet dieselben drei Ausgabemodi und lässt sich gut mit den anderen Signalverarbeitungsfunktionen von SciPy kombinieren. correlation_lags gibt den Lag für jede Ergebnisposition zurück, sodass keine Indexberechnung von Hand nötig ist.
Der Code und die angezeigten Bezeichnungen oder Ausgaben in diesem Abschnitt bleiben auf Englisch.
import numpy as np
from scipy.signal import correlate, correlation_lags
x = np.array([1, 2, 3])
y = np.array([4, 5])
scores = correlate(x, y, mode="full", method="auto")
lags = correlation_lags(len(x), len(y), mode="full")
print(scores.tolist())
print(lags.tolist())
[5, 14, 23, 12]
[-1, 0, 1, 2]
Mit der Option method kann SciPy standardmäßig die Berechnungsstrategie auswählen; die angeforderte Definition der Korrelation ändert sich dadurch nicht. Verwenden Sie beim Vergleich verschiedener Bibliotheken dieselben reellen Eingaben und denselben Modus. Wie NumPy konjugiert auch SciPy bei komplexen Daten die zweite Eingabe, anders als der obige Code in reinem Python. Dieses Beispiel verwendet eindimensionale Arrays mit reellen Werten.
Lags interpretieren und eine Methode auswählen
Bei reellem x als erstem Argument und reellem y als zweitem ordnen NumPy und SciPy die Lags im Modus full von -(len(y) - 1) bis len(x) - 1. Nach dieser Konvention vergleicht ein positiver Lag y mit einem späteren Ausschnitt von x. Prüfen Sie vor der Umrechnung eines Maximums in eine Zeitverzögerung immer die Argumentreihenfolge und Lag-Konvention der Bibliothek; beim Vertauschen der Eingaben kehrt sich die Lag-Richtung um.
Verwenden Sie reines Python, wenn Sie eine Berechnung ohne zusätzliche Abhängigkeiten als Referenz möchten oder mit kleinen Folgen arbeiten. Wählen Sie NumPy für eine kompakte Array-Operation in numerischem Code. SciPy eignet sich, wenn Sie zusätzlich explizite Lag-Werte oder weitere Signalverarbeitungsfunktionen benötigen. Bei gleichmäßig abgetasteten Werten erhalten Sie die Zeitverzögerung, indem Sie den Lag-Index mit dem Abtastintervall multiplizieren. Wenn Sie einen normalisierten Koeffizienten benötigen, müssen Sie die Normalisierung separat festlegen und die Anzahl überlappender Abtastwerte berücksichtigen. Rohe Kreuzkorrelationswerte lassen sich bei unterschiedlicher Überlappung oder Skalierung nicht direkt miteinander vergleichen.
Kreuzkorrelation und Pandas-Korrelation
pandas.Series.corr berechnet einen einzelnen paarweisen Korrelationskoeffizienten für aufeinander abgestimmte Beobachtungen. Die Methode verschiebt eine Folge nicht relativ zur anderen und liefert auch keinen Wert für jeden Lag; sie ist daher keine Kreuzkorrelationsfunktion. Für eine Auswertung über mehrere Lags verwenden Sie NumPy oder SciPy. Wenn Sie Pandas-Daten nutzen, stimmen Sie sie zunächst gezielt aufeinander ab und extrahieren Sie die numerischen Werte. Übergeben Sie diese Arrays anschließend an die gewünschte Implementierung. Für nicht übereinstimmende Indizes und fehlende Werte ist eine ausdrückliche Behandlung erforderlich.