2010-10-20 17 views
9

Tengo dos series de tiempo diferentes con marcas de tiempo que se superponen parcialmente:¿Cómo agregar series de tiempo 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') 

que representa siguientes datos:

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

me gustaría para calcular un promedio ponderado en cada día con coeficientes a (0.3) y b (0.7), mientras que haciendo caso omiso de los valores que faltan:

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 

cuando primero tratar de alinear estas series de tiempo:

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

timeseries consigo enmascara correctamente:

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) 

pero cuando lo hago a1 * 0.3 + b1 * 0.7, no tiene en cuenta los valores, que están presentes en una sola serie de tiempo:

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

¿Qué debo hacer para recibir el esperado?

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

EDITAR: La respuesta debería ser aplicable también a más de dos series de tiempo iniciales con diferentes pesos y los valores de manera diferente que faltan.

Así que si tenemos cuatro series de tiempo con pesos T1 (0,1), T2 (0.2), T3 (0,3) y T4 (0,4), sus pesos en una marca de tiempo dado serán:

  | 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

"más de dos series temporales iniciales"? ¿Te refieres a T1, T2, T3? ¿No es justo ((T1 * agg * T2) * agg * T3)? En tal caso, se puede agregar cualquier cantidad de series de tiempo simplemente aplicando la solución como una reducción. ¿Si no, porque no? –

+0

@ S.Lott - en realidad no. ¿Cómo manejarías los pesos con T1 (0.2), T2 (0.2) y T3 (0.6)? Si en una marca de tiempo dada falta T1, entonces el 0,6 de T3 representa realmente el 75% (T2 tiene entonces el 25%) y no el 60% de todo el grupo. En su lógica ((T1 agg T2) agg T3) esto no funcionaría. – eumiro

+0

@eumiro: ** actualice ** su pregunta con este requisito. –

Respuesta

3

tengo intenté y encontré esto:

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]) 

Esto es aplicable a la pregunta editada con más de una serie de tiempo inicial. Pero espero que alguien lo encuentre mejor.

EDIT: Y esta es mi función:

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]) 

funciona para cualquier número de series de tiempo ;-)

+0

Creo que su 'weightedAvg' es mejor que el que sugerí porque es más simple y requiere menos memoria. ¡Muy agradable! – unutbu

Cuestiones relacionadas