How to get the correlation between two timeseries using Pandas How to get the correlation between two timeseries using Pandas pandas pandas

How to get the correlation between two timeseries using Pandas


You have a number of options using pandas, but you have to make a decision about how it makes sense to align the data given that they don't occur at the same instants.

Use the values "as of" the times in one of the time series, here's an example:

    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

you can see these are off by 30 seconds. The reindex function enables you to align data while filling forward values (getting the "as of" value):

    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

note that 'pad' is also aliased by 'ffill' (but only in the very latest version of pandas on GitHub as of this time!).

Strip seconds out of all your datetimes. The best way to do this is to use 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

Note that if rename causes there to be duplicate dates an Exception will be thrown.

For something a little more advanced, suppose you wanted to correlate the mean value for each minute (where you have multiple observations per second):

    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

These last code snippets may not work if you don't have the latest code from https://github.com/wesm/pandas. If .mean() doesn't work on a GroupBy object per above try .agg(np.mean)

Hope this helps!


By shifting your timestamps you might be losing some accuracy. You can just perform an outer join on your time series filling NaN values with 0 and then you will have the whole timestamps (either it is a shared one or belongs to only one of the datasets). Then you may want to do the correlation function for the columns of your new dataset that will give you the result you are looking for without losing accuracy. This is my code once I was working with time series:

t12 = t1.join(t2, lsuffix='_t1', rsuffix='_t2', how ='outer').fillna(0)t12.corr()

This way you will have all timestamps.