2015-10-26 5 views
6

Ho un DataFrame panda con una colonna TIMESTAMP, che è del tipo di dati datetime64. Si prega di tenere presente, inizialmente questa colonna non è impostata come l'indice; l'indice si trova a soli interi regolari, e le prime righe simile a questa:Media del conteggio giornaliero dei record al mese in un Pandas DataFrame

 TIMESTAMP     TYPE 
0 2014-07-25 11:50:30.640 2 
1 2014-07-25 11:50:46.160 3 
2 2014-07-25 11:50:57.370 2 

C'è un numero arbitrario di record per ogni giorno, e ci possono essere giorni senza dati. Quello che sto cercando di ottenere è il numero medio di numero di registrazioni giornaliere al mese quindi tracciarlo come un grafico a barre con mesi nell'asse x (aprile 2014, maggio 2014 ... ecc.). Sono riuscito a calcolare questi valori utilizzando il codice qui sotto

dfWIM.index = dfWIM.TIMESTAMP  
for i in range(dfWIM.TIMESTAMP.dt.year.min(),dfWIM.TIMESTAMP.dt.year.max()+1): 
    for j in range(1,13): 
     print dfWIM[(dfWIM.TIMESTAMP.dt.year == i) & (dfWIM.TIMESTAMP.dt.month == j)].resample('D', how='count').TIMESTAMP.mean() 

che dà il seguente risultato:

nan 
nan 
3100.14285714 
6746.7037037 
9716.42857143 
10318.5806452 
9395.56666667 
9883.64516129 
8766.03225806 
9297.78571429 
10039.6774194 
nan 
nan 
nan 

Questo è ok così com'è, e con un po 'più di lavoro, posso mappare ai risultati di correggere i nomi dei mesi, quindi traccia il grafico a barre. Tuttavia, non sono sicuro che questo sia il modo corretto/migliore e sospetto che ci possa essere un modo più semplice per ottenere i risultati usando Pandas.

Sarei lieto di sapere cosa ne pensate. Grazie!

NOTA: Se non si imposta la colonna TIMESTAMP come indice, viene visualizzato un errore "operazione di riduzione" che significa "non consentito per questo dtype".

risposta

8

Penso che vorrai fare due turni di groupby, prima di raggruppare di giorno e contare le istanze, e poi di raggruppare per mese e calcolare la media dei conteggi giornalieri. Potresti fare qualcosa di simile.

Prima io generare alcuni dati falsi che appare come la tua:

import pandas as pd 

# make 1000 random times throughout the year 
N = 1000 
times = pd.date_range('2014', '2015', freq='min') 
ind = np.random.permutation(np.arange(len(times)))[:N] 

data = pd.DataFrame({'TIMESTAMP': times[ind], 
        'TYPE': np.random.randint(0, 10, N)}) 
data.head() 

enter image description here

Ora io farò le due groupbys utilizzando pd.TimeGrouper e tracciare i conteggi medi mensili:

import seaborn as sns # for nice plot styles (optional) 

daily = data.set_index('TIMESTAMP').groupby(pd.TimeGrouper(freq='D'))['TYPE'].count() 
monthly = daily.groupby(pd.TimeGrouper(freq='M')).mean() 
ax = monthly.plot(kind='bar') 

enter image description here

La formattazione lungo l'asse x lascia qualcosa a desiderare, ma è possibile modificarla se necessario.

+0

Non riuscivo a capire come farlo usando 'groupby'. Risulta che 'TimeGrouper' è il trucco. Molte grazie! La formattazione – marillion

+0

lungo l'asse x per il diagramma a barre con serie temporali era molto più complicata di quanto pensassi. La soluzione è su http://stackoverflow.com/questions/33642388/pandas-bar-plot-with-multiindex-dataframe se qualcuno si blocca nello stesso punto. – marillion