2014-10-22 26 views
8

Come posso creare un boxplot per una serie temporale di panda in cui ho una casella per ogni giorno?Boxplot in serie temporali nei panda

set di dati campione di dati orari in cui una scatola dovrebbe essere costituito da 24 valori:

import pandas as pd 
n = 480 
ts = pd.Series(randn(n), 
       index=pd.date_range(start="2014-02-01", 
            periods=n, 
            freq="H")) 
ts.plot() 

Sono consapevole che avrei potuto fare una colonna in più per il giorno, ma mi piacerebbe avere una corretta etichettatura asse x e la funzionalità x-limit (come in ts.plot()), quindi essere in grado di lavorare con l'indice datetime sarebbe grandioso.

C'è una domanda simile per R/ggplot2 here, se aiuta a chiarire cosa voglio.

+1

C'è una soluzione forse più bello per questo [qui] (https://stackoverflow.com/questions/17194581/best-way-to-generate-day-of-week-boxplots-from-a- pandas-timeseries) che usa solo Pandas, le sue funzioni '.boxplot()' e '.pivot()' e non richiede Seaborn – cardamom

risposta

6

Se è un'opzione per te, ti consigliamo di utilizzare Seaborn, che è un wrapper per Matplotlib. Puoi farlo da solo eseguendo il loop dei gruppi dalle tue timeeries, ma è molto più lavoro.

import pandas as pd 
import numpy as np 
import seaborn 
import matplotlib.pyplot as plt 

n = 480 
ts = pd.Series(np.random.randn(n), index=pd.date_range(start="2014-02-01", periods=n, freq="H")) 


fig, ax = plt.subplots(figsize=(12,5)) 
seaborn.boxplot(ts.index.dayofyear, ts, ax=ax) 

che dà: enter image description here

Nota che sto passando il day of year come grouper a Seaborn, se i dati si estende su più anni questo non avrebbe funzionato. Si potrebbe quindi prendere in considerazione qualcosa di simile:

ts.index.to_series().apply(lambda x: x.strftime('%Y%m%d')) 

Modifica, per ogni 3 ore si potrebbe usare questo come una cernia, ma funziona solo se non ci sono minuti o inferiore definiti. :

[(dt - datetime.timedelta(hours=int(dt.hour % 3))).strftime('%Y%m%d%H') for dt in ts.index] 
+0

In realtà io uso comunque seaborn, quindi questa è sicuramente un'opzione. Grazie!/modifica: esiste un modo per utilizzarlo per tempi arbitrari, ad es. Box box di 3 ore, box box di 7 giorni, ecc.? –

+1

Sì, puoi inviare qualsiasi cosa alla cernia Seaborns. La sfida è definire i gruppi dall'indice della serie. Ho aggiunto un esempio per periodi di 3 ore. Qualcosa del genere potrebbe funzionare per periodi di tempo arbitrari. Sfortunatamente non è molto leggibile, forse una semplificazione è possibile usando Pandas 'Timegrouper'. L'apertura di una domanda specifica sulla cernia di Seaborn potrebbe essere di aiuto alle persone che usano molto Seaborn, cosa che non lo sono. –

5

(Non abbastanza rep per commentare soluzione accettata, quindi l'aggiunta di una risposta, invece.)

Il codice accettato ha due piccoli errori: (1) è necessario aggiungere numpy importazione e (2) nned per scambiare i parametri x e nell'istruzione boxplot. Quanto segue produce la trama mostrata.

import numpy as np 
import pandas as pd 
import seaborn 
import matplotlib.pyplot as plt 

n = 480 
ts = pd.Series(np.random.randn(n), index=pd.date_range(start="2014-02-01", periods=n, freq="H")) 

fig, ax = plt.subplots(figsize=(12,5)) 
seaborn.boxplot(ts.index.dayofyear, ts, ax=ax) 
+0

Sei il migliore! – zkytony

+0

Grande. Ho modificato la risposta accettata. –

Problemi correlati