Ho due serie di dati che sto cercando di correlare. Sembrano simili alla funzione arctan
, quindi l'ho usata come modello per capire come eseguire l'elaborazione del segnale.Correlazione incrociata della funzione non periodica con NumPy
x = linspace(-15, 15, 2**13)
f1 = arctan(x)
f2 = arctan(x + 2)
La domanda che ho bisogno di rispondere è, quanto ho bisogno di spostare il segnale verde per farlo (per lo più) sovrapposizione con quello blu? Ho pensato che sarebbe stato semplice trovare il massimo nella funzione di cross-correlazione di f1
e f2
, e ho seguito ampiamente il consiglio qui: How to correlate two time series with gaps and different time bases?. Questo è quello che ho cercato
c = correlate(f1, f2, 'full')
s = arange(1-2**13, 2**13)
dx = 30/2**13
shift = s[c.argmax()]*dx
mi aspetterei shift
di eguagliare più o meno esattamente 2, ma in realtà è solo 0.234
. Questo non ha alcun senso per me; Ho trovato la coordinata x del massimo nella correlazione incrociata, che dovrebbe essere trovata dove c'è la massima sovrapposizione dei due segnali.
Qualche idea su come calcolare questa quantità per questo tipo di funzione?
EDIT: Vorrei aggiungere, per i miei dati reali, tutti i valori saranno tra zero e uno
EDIT EDIT: Le seguenti funzioni sono in realtà più come il mio vero dati:
x = linspace(-15, 15, 400)
f1 = (arctan(-x) + pi/2)/pi
f2 = (arctan(-x + 2) + pi/2)/pi
Quindi, utilizzando la formula qui data: http://paulbourke.net/miscellaneous/correlate/ posso scrivere una funzione di correlazione incrociata che pads i dati da aggiungere quelli a sinistra e zeri a destra:
def xcorr(x, y);
mx = x.mean()
my = y.mean()
sx = x.std()
sy = y.std()
r = zeros(2*len(x))
for d in range(-len(x), len(x)):
csum = 0
for i in range(0, len(x):
yindx = i - d
if i - d < 0:
yval = 1
elif i - d >= len(x):
yval = 0
else:
yval = y[yindx]
csum += (x[i] - mx) * (yval - my)
r[d + len(x)] = csum/(sx * sy)
return r
Con questa funzione, ora posso fare
c = xcorr(f1, f2)
s = arange(-400, 400)
dx = 30/400
shift = s[c.argmax()] * dx
che esce a 2.025, che è il più vicino si può arrivare a 2 con questa precisione. Quindi sembra che Jamie avesse ragione, il problema è in che modo il numding di correlate
fa il riempimento dei segnali.
Quindi, ovviamente, la mia funzione xcorr
è molto lenta così com'è. La domanda ora è, c'è un modo per fare in modo che NumPy faccia una cosa simile, o dovrei semplicemente scrivere il mio algoritmo in C usando ctypes
?
Interessante- se aggiungo 1.5 a f1 e f2 per fare sempre positivi, il turno diventa zero ... –
@Essi allora dovresti rendere il tuo commento una risposta. Forse aggiungere un link per ulteriori spiegazioni. –
Sfortunatamente, un controllo veloce su http://en.wikipedia.org/wiki/Cross-correlation non riporta alcuna specifica sul valore assoluto necessario per i segnali di input. Non so se la funzione numpy.correlate abbia tali limiti. –