2010-10-20 5 views
9

j'ai deux séries chronologiques différentes avec des horodatages se chevauchant partiellement:Comment agréger des timeseries en Python?

import scikits.timeseries as ts 
from datetime import datetime 
a = ts.time_series([1,2,3], dates=[datetime(2010,10,20), datetime(2010,10,21), datetime(2010,10,23)], freq='D') 
b = ts.time_series([4,5,6], dates=[datetime(2010,10,20), datetime(2010,10,22), datetime(2010,10,23)], freq='D') 

qui représente données suivantes:

Day: 20. 21. 22. 23. 
    a: 1 2 - 3 
    b: 4 - 5 6 

Je souhaite calculer une moyenne pondérée sur tous les jours avec des coefficients a (0,3) et b (0,7), tout en ignorant les valeurs manquantes:

Day 20.: (0.3 * 1 + 0.7 * 4)/(0.3 + 0.7) = 3.1/1. = 3.1 
Day 21.: (0.3 * 2   )/(0.3  ) = 0.6/0.3 = 2 
Day 22.: (   0.7 * 5)/(  0.7) = 3.5/0.7 = 5 
Day 23.: (0.3 * 3 + 0.7 * 6)/(0.3 + 0.7) = 3.1/1. = 5.1 

lorsque je tente d'abord d'aligner ces timeseries:

a1, b1 = ts.aligned(a, b) 

je suis correctement masquée timeseries:

timeseries([1 2 -- 3], 
    dates = [20-Oct-2010 ... 23-Oct-2010], 
    freq = D) 

timeseries([4 -- 5 6], 
    dates = [20-Oct-2010 ... 23-Oct-2010], 
    freq = D) 

mais quand je fais a1 * 0.3 + b1 * 0.7, il ne tient pas compte des valeurs, qui sont présents dans un timeseries seulement:

timeseries([3.1 -- -- 5.1], 
    dates = [20-Oct-2010 ... 23-Oct-2010], 
    freq = D) 

Que dois-je faire pour recevoir le attendu?

timeseries([3.1 2. 5. 5.1], 
    dates = [20-Oct-2010 ... 23-Oct-2010], 
    freq = D) 

EDIT: La réponse devrait être applicable aussi à plus de deux timeseries initiales avec des poids et des valeurs différentes différemment manquantes.

Donc, si nous disposons de quatre séries temporelles avec des poids T1 (0,1), T2 (0,2), T3 (0,3) et T4 (0,4), leur poids à une estampille temporelle donnée seront:

  | T1 | T2 | T3 | T4 | 
weight  | 0.1 | 0.2 | 0.3 | 0.4 | 
------------------------------------- 
all present | 10% | 20% | 30% | 40% | 
T1 missing |  | 22% | 33% | 45% | 
T1,T2 miss. |  |  | 43% | 57% | 
T4 missing | 17% | 33% | 50% |  | 
etc. 
+0

"plus de deux timeseries initiales"? Vous voulez dire T1, T2, T3? N'est-ce pas juste ((T1 * agg * T2) * agg * T3)? Dans ce cas, n'importe quel nombre de séries chronologiques peut être agrégé en appliquant simplement la solution comme une réduction. Si non, pourquoi pas? –

+0

@ S.Lott - pas vraiment. Comment gérez-vous les poids avec T1 (0,2), T2 (0,2) et T3 (0,6)? Si à un instant donné T1 est manquant, alors le 0,6 de T3 représente en réalité 75% (T2 a alors 25%) et pas 60% du groupe entier. Dans votre logique ((T1 agg T2) agg T3) cela ne fonctionnerait pas. – eumiro

+0

@eumiro: S'il vous plaît ** mettre à jour ** votre question avec cette exigence. –

Répondre

3

je essayé et trouvé ceci:

aWgt = 0.3 
bWgt = 0.7 

print (np.where(a1.mask, 0., a1.data * aWgt) + 
     np.where(b1.mask, 0., b1.data * bWgt))/(np.where(a1.mask, 0., aWgt) + 
               np.where(b1.mask, 0., bWgt)) 

# array([ 3.1, 2. , 5. , 5.1]) 

Ceci est applicable à la question éditée avec plus d'un timeseries initial. Mais j'espère que quelqu'un trouvera mieux.

EDIT: Et voici ma fonction:

def weightedAvg(weightedTimeseries): 
    sumA = np.sum((np.where(ts.mask, 0., ts.data * weight) for ts, weight in weightedTimeseries), axis=0) 
    sumB = np.sum((np.where(ts.mask, 0., weight) for ts, weight in weightedTimeseries), axis=0) 
    return np.divide(sumA, sumB) 

weightedAvg(((a1, 0.3), (bb, 0.7))) 
# array([ 3.1, 2. , 5. , 5.1]) 

Works pour un certain nombre de séries chronologiques de

+0

Je pense que votre weightedAvg est meilleur que celui que j'ai suggéré parce qu'il est plus simple et prend moins de mémoire. Très agréable! – unutbu

Questions connexes