2012-12-17 19 views
5

Possiedo un ampio insieme di serie temporali di dati a intervalli di 30 minuti e cerco di eseguire una finestra scorrevole su questo insieme di dati, ma separatamente per ogni punto della giornata utilizzando i panda.Media finestra scorrevole attraverso gli assi temporali

Non sono uno statistico e non sono bravo a pensare o scrivere codice per questo tipo di lavoro, ma qui è il mio maldestro tentativo di fare ciò che voglio. Sto davvero cercando aiuto per migliorarlo, perché so che ci sarà un modo migliore per farlo, possibilmente utilizzando MultiIndex e qualche iterazione corretta? Ma ho faticato a farlo attraverso gli "assi del tempo".

def sliding_window(run,data,type='mean'): 
    data = data.asfreq('30T') 
    for x in date_range(run.START, run.END, freq='1d'): 
     if int(datetime.strftime(x, "%w")) == 0 or int(datetime.strftime(x, "%w")) == 6: 
      points = data.select(weekends).truncate(x - relativedelta(days=run.WINDOW),x + relativedelta(days=run.WINDOW)).groupby(lambda date: minutes(date, x)).mean() 
     else: 
      points = data.select(weekdays).truncate(x - relativedelta(days=run.WINDOW),x + relativedelta(days=run.WINDOW)).groupby(lambda date: minutes(date, x)).mean() 
     for point in points.index: 
      data[datetime(x.year,x.month,x.day,point.hour,point.minute)] = points[point] 
    return data 

run.START, run.END e run.WINDOW sono due punti all'interno dati e 45 (giorni). Ho osservato molto questo codice quindi non sono sicuro di cosa abbia senso (se ne ha) per qualcun altro, ti preghiamo di chiedere in modo che io possa chiarire qualsiasi altra cosa.

RISOLTO: (Soluzione per gentile concessione di crewbum)

La funzione modificata che, come previsto va stupidamente veloce:

def sliding_window(run,data,am='mean',days='weekdays'): 
    data = data.asfreq('30T') 
    data = DataFrame({'Day': [d.date() for d in data.index], 'Time': [d.time() for d in data.index], 'Weekend': [weekday_string(d) for d in data.index], 'data': data}) 
    pivot = data.pivot_table(values='data', rows='Day', cols=['Weekend', 'Time']) 
    pivot = pivot[days] 
    if am == 'median': 
     mean = rolling_median(pivot, run.WINDOW*2, min_periods=1) 
    mean = rolling_mean(pivot, run.WINDOW*2, min_periods=1) 
    return DataFrame({'mean': unpivot(mean), 'amax': np.tile(pivot.max().values, pivot.shape[0]), 'amin': np.tile(pivot.min().values, pivot.shape[0])}, index=data.index) 

La funzione UNPIVOT:

def unpivot(frame): 
    N, K = frame.shape 
    return Series(frame.values.ravel('C'), index=[datetime.combine(d[0], d[1]) for d in zip(np.asarray(frame.index).repeat(K), np.tile(np.asarray(frame.ix[0].index), N))]) 

Il centro = True su sliding_mean sembra essere rotto al momento, lo archivierò in github se ne avrò la possibilità.

+0

Hai visto/provato il built-in di laminazione funzione di media http:?? //pandas.pydata.org/pandas-docs/stable/generated/pandas.stats.moments.rolling_mean.html evidenziare = rotolamento # pandas.stats.moments.rolling_mean – Garrett

+0

Cercando di chiarire cosa si sta tentando di fare: si desidera calcolare la media di tutti i valori nell'intervallo compreso tra -45 e +45, ma raggruppati per 24 ore. Ad esempio, la media di tutti i dati (91) alle 13:00 e la media separata di tutti i dati alle 13:30 ecc. Perché "fare una finestra scorrevole" è piuttosto indefinito: una finestra scorrevole di cosa? – Evert

+0

Inoltre, perché la separazione nei giorni feriali e nei fine settimana? Immagino che sia logico per i dati presi in considerazione? – Evert

risposta

4

Se sei interessato a MultiIndex, controlla df.pivot_table(). Creerà automaticamente un MultiIndex quando vengono passate più chiavi nei parametri row e/o cols.

Ad esempio, si supponga di voler ruotare i dati in modo che ci siano colonne separate per ogni fine settimana e blocco di 30 minuti non di fine settimana del giorno; è possibile farlo aggiungendo colonne Day, Weekend e TOD (ora del giorno) a DataFrame e quindi passando i nomi di colonna a pivot_table come segue.

pivot = df.pivot_table(values='Usage', rows='Day', cols=['TOD', 'Weekend']) 

In questo formato, pd.rolling_mean() (o una funzione della creazione) può essere facilmente applicato alle colonne di pivot. pd.rolling_mean(), come tutte le funzioni rolling/moving in panda, accetta anche un parametro center per le finestre scorrevoli centrate.

pd.rolling_mean(pivot, 90, center=True, min_periods=1) 
+0

Incredibile. Grazie mille. –

Problemi correlati