2013-03-18 6 views
5

J'ai un jeu de données avec les trois premières colonnes suivantes. Inclure l'identifiant du panier (identifiant unique), le montant de la vente (dollars) et la date de la transaction. Je veux calculer la colonne suivante pour chaque ligne de l'ensemble de données, et je voudrais le faire en Python.Python - alignement des séries temporelles et fonctions "à jour"

Vente précédente du même panier (le cas échéant); Nombre de vente actuellement jusqu`à présent; Moyenne à ce jour pour le panier actuel (si disponible); Max à ce jour pour le panier actuel (si disponible)

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  

Je suis assez nouveau avec Python, et je lutte vraiment trouver quoi que ce soit pour le faire d'une façon élégante. J'ai trié les données (comme ci-dessus) par NID et Date, afin que je puisse obtenir la vente précédente en vrac en avançant de un pour chaque panier. Aucune idée comment obtenir le MeanToDate et MaxToDate d'une manière efficace en dehors de la boucle ... des idées?

+0

Quel est le format de votre 'ensemble de données' actuel (les trois premières colonnes)? S'agit-il d'un fichier ou utilisez-vous actuellement une sorte de structure de données? – askewchan

+0

désolé, j'ai oublié de mentionner. il provient d'un fichier texte, mais est stocké dans un dataframe pandas. –

Répondre

4

Cela devrait faire l'affaire:

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

Vous pouvez en savoir plus sur le regroupement/agrégation here.

+0

La fonction cumulative est tout simplement génial - Merci! Pourquoi l'hypothèse de ne pas avoir plus d'une transaction par panier par jour? –

+0

Si l'index n'est pas unique, 'concat' ne pourra pas aligner correctement les colonnes, car il y aura plusieurs valeurs pour certains indices, si cela a du sens. – mtth

+0

a du sens ... et malheureusement il y a plusieurs dates pour le même panier. Lorsque vous suggérez d'utiliser le resample, est-ce que c'est dans le "handler" ou avant pour le dataframe? J'espère que j'ai demandé quelque chose qui a du sens, car il n'est pas vraiment clair ce que le rééchantillonnage est en train de faire (besoin de rentrer à la maison d'abord!) –

Questions connexes