2011-06-24 11 views
10

Mam dwa zestawy dat temperatury, które mają odczyty w regularnych (ale różnych) odstępach czasu. Próbuję uzyskać korelację między tymi dwoma zestawami danych.Jak uzyskać korelację między dwoma seriami przy użyciu Pandas

Grałem z Pandas, aby spróbować to zrobić. Stworzyłem dwie serie czasowe i używam TimeSeriesA.corr(TimeSeriesB). Jeśli jednak czasy w 2 timeSeries nie zgadzają się dokładnie (zazwyczaj są wyłączone przez sekundy), otrzymuję Null jako odpowiedź. Mógłbym dostać przyzwoity odpowiedź gdybym mógł:

a) Interpolate/fill razy brakuje w każdym timeseries (wiem, że to jest możliwe w Pand, ja po prostu nie wiem jak to zrobić)

b) usuń sekundy z obiektów python datetime (ustawiaj sekundy na 00, bez zmiany minut). stracę stopień dokładności, ale nie ogromne ilości

c) wykorzystanie coś innego w Pand dostać korelację pomiędzy dwoma timeseries

d) stosowanie coś w Pythona aby uzyskać korelację pomiędzy dwoma listami pływa, każdy zmiennoprzecinkowy ma odpowiedni obiekt datetime, biorąc pod uwagę czas.

Ktoś ma jakieś sugestie?

Odpowiedz

12

Masz wiele opcji przy użyciu pand, ale musisz podjąć decyzję o tym, jak sensowne jest wyrównywanie danych, biorąc pod uwagę, że nie występują one w tym samym momencie.

Użyj wartości „jako o” czasach w jednym szeregu czasowego, oto przykład:

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 

widać są one wyłączone przez 30 sekund. Funkcja reindex pozwala wyrównać danych podczas wypełniania naprzód wartości (uzyskiwanie „jako o” wartości):

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 

uwaga, że ​​„pad” jest również aliasem przez „ffill” (ale tylko w najnowszej wersji pandy na GitHub od tego czasu!).

Pozbądź się sekund ze wszystkich datetimes. Najlepszym sposobem, aby to zrobić jest użycie 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 

pamiętać, że jeśli zmiana nazwy powoduje tam być zdublowane daty Exception zostanie wyrzucony.

Na coś bardziej zaawansowanego, załóżmy, że chciał, aby skorelować wartości średniej dla każdego minutę (gdzie masz kilka uwag na sekundę):

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 

Te ostatnie fragmenty kodu mogą nie działać, jeśli nie mają najnowszego kodu od https://github.com/wesm/pandas. Jeśli numer .mean() nie działa na obiekcie GroupBy, spróbuj .agg(np.mean)

Mam nadzieję, że to pomoże!

+0

Ha, masz to zanim mogłem: -) ... –

+0

Jeśli czytam ostatnią część w prawo, ostatnia część oblicza średnią dla wartości od 00 do 60 sekund (średnia dla XX: XX: 30, nie XX: XX: 00) i przypisuje wynik do XX: XX : 00. Prostym sposobem obejścia tego byłoby "date.replace (second = 30)", zbyt skomplikowanym sposobem uzyskania średnich na minutę byłoby: 'ts_mean = seriesT.groupby (lambda date: date.replace (second = 0) if date.second <30 else date.replace (second = 0) + timedelta (minutes = 1)). mean() ' – user814005

Powiązane problemy