Как получить корреляцию между двумя таймерами с помощью Pandas

У меня есть два набора температурных дат, которые имеют показания на регулярных (но разных) временных интервалах. Я пытаюсь получить корреляцию между этими двумя наборами данных.

Я играл с Pandas, чтобы попытаться это сделать. Я создал два раза, и я использую TimeSeriesA.corr(TimeSeriesB). Однако, если времена в 2 timeSeries не совпадают точно (они обычно отключены за секунды), я получаю Null в качестве ответа. Я мог бы получить достойный ответ, если бы мог:

a) Interpolate/fill missing times в каждом TimeSeries (я знаю, что это возможно в Pandas, я просто не знаю, как это сделать)

b) отделите секунды от объектов datetime python (установите секунды до 00, без изменения минут). Я бы потерял определенную степень точности, но не огромную сумму

c) Используйте что-то еще в Pandas, чтобы получить корреляцию между двумя timeSeries

d) Используйте что-то в python, чтобы получить корреляцию между двумя списками поплавков, причем каждый float имеет соответствующий объект datetime, принимая во внимание время.

У кого-нибудь есть предложения?

Ответ 1

У вас есть ряд опций с использованием pandas, но вы должны принять решение о том, как имеет смысл выровнять данные, если они не происходят в те же моменты.

Используйте значения "по времени" в одном из временных рядов, здесь пример:

    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

вы можете видеть, что они отключены на 30 секунд. Функция reindex позволяет выровнять данные при заполнении форвардных значений (получение значения "от" ):

    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

обратите внимание, что "pad" также псевдоним "ffill" (но только в самой последней версии pandas на GitHub на данный момент!).

Удалите секунды из всех ваших datetime. Лучший способ сделать это - использовать 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

Обратите внимание, что если переименование приведет к дублированию дат, будет выбрано значение Exception.

Для чего-то более продвинутого, предположим, что вы хотите скорректировать среднее значение для каждой минуты (где у вас есть несколько наблюдений в секунду):

    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

Эти последние фрагменты кода могут не работать, если у вас нет последнего кода из https://github.com/wesm/pandas. Если .mean() не работает над объектом GroupBy, указанным выше, попробуйте .agg(np.mean)

Надеюсь, это поможет!