2011-06-24 20 views
10

Tengo dos conjuntos de fecha de temperatura, que tienen lecturas a intervalos de tiempo regulares (pero diferentes). Estoy tratando de obtener la correlación entre estos dos conjuntos de datos.Cómo obtener la correlación entre dos series de tiempo usando Pandas

He estado jugando con Pandas para intentar hacer esto. Creé dos series de tiempo y estoy usando TimeSeriesA.corr(TimeSeriesB). Sin embargo, si los tiempos en los 2 timeSeries no coinciden exactamente (generalmente están desactivados por segundos), obtengo Null como respuesta. Podría obtener una respuesta decente si pudiera:

a) Interpolar/relleno veces falta en cada TimeSeries (Sé que esto es posible en pandas, yo simplemente no saben cómo hacerlo)

b) quite los segundos de los objetos de fecha y hora de Python (establezca los segundos en 00, sin cambiar los minutos). Voy a perder un grado de exactitud, pero no una gran cantidad

c) Utilizar algo más en las pandas para obtener la correlación entre dos series temporales

d) utilizar algo en Python para obtener la correlación entre dos listas de flota, cada flotante tiene un objeto datetime correspondiente, teniendo en cuenta el tiempo.

¿Alguien tiene alguna sugerencia?

Respuesta

12

Tiene varias opciones para usar pandas, pero tiene que tomar una decisión acerca de cómo tiene sentido alinear los datos ya que no ocurren en los mismos instantes.

Utilice los valores "como la de" los tiempos en una de las series de tiempo, he aquí un ejemplo:

In [15]: ts 
    Out[15]: 
    2000-01-03 00:00:00 -0.722808451504 
    2000-01-04 00:00:00 0.0125041039477 
    2000-01-05 00:00:00 0.777515530539 
    2000-01-06 00:00:00 -0.35714026263 
    2000-01-07 00:00:00 -1.55213541118 
    2000-01-10 00:00:00 -0.508166334892 
    2000-01-11 00:00:00 0.58016097981 
    2000-01-12 00:00:00 1.50766289013 
    2000-01-13 00:00:00 -1.11114968643 
    2000-01-14 00:00:00 0.259320239297 



    In [16]: ts2 
    Out[16]: 
    2000-01-03 00:00:30 1.05595278907 
    2000-01-04 00:00:30 -0.568961755792 
    2000-01-05 00:00:30 0.660511172645 
    2000-01-06 00:00:30 -0.0327384421979 
    2000-01-07 00:00:30 0.158094407533 
    2000-01-10 00:00:30 -0.321679671377 
    2000-01-11 00:00:30 0.977286027619 
    2000-01-12 00:00:30 -0.603541295894 
    2000-01-13 00:00:30 1.15993249209 
    2000-01-14 00:00:30 -0.229379534767 

se puede ver estos son fuera por 30 segundos. La función reindex permite alinear los datos mientras que el llenado hacia adelante valores (lograr que el "como" de valor):

In [17]: ts.reindex(ts2.index, method='pad') 
    Out[17]: 
    2000-01-03 00:00:30 -0.722808451504 
    2000-01-04 00:00:30 0.0125041039477 
    2000-01-05 00:00:30 0.777515530539 
    2000-01-06 00:00:30 -0.35714026263 
    2000-01-07 00:00:30 -1.55213541118 
    2000-01-10 00:00:30 -0.508166334892 
    2000-01-11 00:00:30 0.58016097981 
    2000-01-12 00:00:30 1.50766289013 
    2000-01-13 00:00:30 -1.11114968643 
    2000-01-14 00:00:30 0.259320239297 

    In [18]: ts2.corr(ts.reindex(ts2.index, method='pad')) 
    Out[18]: -0.31004148593302283 

nota que 'almohadilla' también es alias de 'ffill' (pero sólo en la última versión de pandas en GitHub a partir de este momento!).

Elimine segundos de todas sus fechas. La mejor manera de hacer esto es utilizar rename

In [25]: ts2.rename(lambda date: date.replace(second=0)) 
    Out[25]: 
    2000-01-03 00:00:00 1.05595278907 
    2000-01-04 00:00:00 -0.568961755792 
    2000-01-05 00:00:00 0.660511172645 
    2000-01-06 00:00:00 -0.0327384421979 
    2000-01-07 00:00:00 0.158094407533 
    2000-01-10 00:00:00 -0.321679671377 
    2000-01-11 00:00:00 0.977286027619 
    2000-01-12 00:00:00 -0.603541295894 
    2000-01-13 00:00:00 1.15993249209 
    2000-01-14 00:00:00 -0.229379534767 

Tenga en cuenta que si cambio de nombre provoca que haya fechas duplicadas un Exception será lanzada.

Para algo un poco más avanzado, suponga que desea correlacionar el valor medio de cada minuto (donde tiene varias observaciones por segundo):

In [31]: ts_mean = ts.groupby(lambda date: date.replace(second=0)).mean() 

    In [32]: ts2_mean = ts2.groupby(lambda date: date.replace(second=0)).mean() 

    In [33]: ts_mean.corr(ts2_mean) 
    Out[33]: -0.31004148593302283 

Estos últimos fragmentos de código pueden no funcionar si no tiene el código más reciente de https://github.com/wesm/pandas. Si .mean() no funciona en un objeto GroupBy por encima intente .agg(np.mean)

Espero que esto ayude!

+0

Ja, lo tienes antes de que pudiera: -) ... –

+0

Si estoy leyendo la última parte a la derecha, la última parte calcula la media para valores entre 00 y 60 segundos (la media para XX: XX: 30, no XX: XX: 00), y asigna el resultado a XX: XX : 00. La forma más sencilla de solucionar esto sería 'date.replace (second = 30)', una forma demasiado compleja de obtener los promedios por minuto sería: 'ts_mean = seriesT.groupby (lambda date: date.replace (second = 0) if date.second <30 else date.replace (second = 0) + timedelta (minutes = 1)). mean() ' – user814005

Cuestiones relacionadas