2013-03-18 7 views
5

Ho un set di dati con le seguenti prime tre colonne. Includi ID carrello (identificativo univoco), Importo vendita (in dollari) e data della transazione. Voglio calcolare la seguente colonna per ogni riga del set di dati, e mi piacerebbe farlo in Python.Python - funzioni di allineamento temporale e "data"

Vendita precedente dello stesso paniere (se presente); Conteggio vendite fino ad oggi per il paniere corrente; Mean To Date per il carrello corrente (se disponibile); Max A Data per il carrello attuale (se disponibile)

Basket Sale Date  PrevSale SaleCount MeanToDate MaxToDate 
88  $15 3/01/2012    1  
88  $30 11/02/2012  $15  2   $23  $30 
88  $16 16/08/2012  $30  3   $20  $30 
123  $90 18/06/2012    1  
477  $77 19/08/2012    1  
477  $57 11/12/2012  $77  2   $67  $77 
566  $90 6/07/2012    1  

Sono abbastanza nuovo con Python, e ho davvero fatica a trovare qualcosa da fare in un modo elegante. Ho ordinato i dati (come sopra) da BasketID e Data, così posso ottenere la vendita precedente alla rinfusa spostando in avanti di uno per ogni singolo paniere. Nessun indizio su come ottenere MeanToDate e MaxToDate in modo efficiente, a parte il looping ... qualche idea?

+0

Quale formato è il "set di dati" corrente in (le prime tre colonne)? È un file o stai usando una sorta di struttura dati al momento? – askewchan

+0

scusa, ho dimenticato di dirlo. proviene da un file di testo, ma è memorizzato nel dataframe di un panda. –

risposta

4

Questo dovrebbe fare il trucco:

from pandas import concat 
from pandas.stats.moments import expanding_mean, expanding_count 

def handler(grouped): 
    se = grouped.set_index('Date')['Sale'].sort_index() 
    # se is the (ordered) time series of sales restricted to a single basket 
    # we can now create a dataframe by combining different metrics 
    # pandas has a function for each of the ones you are interested in! 
    return concat(
     { 
      'MeanToDate': expanding_mean(se), # cumulative mean 
      'MaxToDate': se.cummax(),   # cumulative max 
      'SaleCount': expanding_count(se), # cumulative count 
      'Sale': se,      # simple copy 
      'PrevSale': se.shift(1)   # previous sale 
     }, 
     axis=1 
    ) 

# we then apply this handler to all the groups and pandas combines them 
# back into a single dataframe indexed by (Basket, Date) 
# we simply need to reset the index to get the shape you mention in your question 
new_df = df.groupby('Basket').apply(handler).reset_index() 

Si può leggere di più su di raggruppamento/aggregazione here.

+0

La funzione cumulativa è semplicemente fantastica - Grazie! Perché l'ipotesi di non avere più di una transazione per paniere al giorno? –

+0

Se l'indice non è univoco, 'concat' non sarà in grado di allineare correttamente le colonne, poiché ci saranno più valori per alcuni indici, se questo ha senso. – mtth

+0

ha senso ... e sfortunatamente ci sono più date per lo stesso paniere. Quando stai suggerendo di usare resample, è all'interno del "gestore" o prima per il dataframe? Spero di aver chiesto qualcosa di sensato, in quanto non è chiaro cosa stia effettivamente ricampionando (è necessario tornare a casa prima!) –