2016-10-12 4 views
2

J'ai un dataframe Pandas avec les colonnes suivantesMRR en Python Pandas dataframe

date | months | price

Je calcule certains paramètres de base BI. J'ai fait le revenu net en regroupant les dataframe à la date et la somme du prix:

df = df[["Date", "Price"]].groupby(df['Date'])["Price"].sum().reset_index()

Maintenant, je veux trouver le MRR, qui est semblable au revenu net, mais au cas où les mois de colonne ont plus que 1 mois, le prix devrait être "déplacé" également aux mois suivants. Et aussi, il est groupé par mois et non par jour. Par exemple, si je suis en janvier 2016 et que j'ai une rangée avec 3 mois et un prix de 30 $, je devrais ajouter 10 $ à janvier, 10 $ à février et 10 $ à mars.

Ma première idée était de parcourir la base de données, de garder une trace des mois et du montant du prix que je devrais "déplacer" les mois suivants et de créer une nouvelle base de données manuellement.

Mais, d'abord, y a-t-il un moyen Python pour les Pandas de le faire?

données pour reproduire un dataframe:

import pandas as pd 
df = pd.DataFrame({'date': ['01-01-2016', '05-01-2016', '10-01-2016','04-02-2016'], 
        'months': [1, 3, 1, 6], 
        'price': [40, 60, 20, 60]}) 

Résultat souhaité:

Date   | MRR 
January 2016 | 80 
February 2016| 30 
March 2016 | 10 
April 2016 | 10 
May 2016  | 10 
June 2016 | 10 
July 2016 | 10 

Et les résultats calculés comme celui-ci pour chaque ligne

January 2016 = 40 + 20 + 20 + 0 
February 2016 = 0 + 20 + 0 + 10 
March 2016 = 0 + 0 + 0 + 10 
April 2016 = 0 + 0 + 0 + 10 
May 2016 = 0 + 0 + 0 + 10 
June 2016 = 0 + 0 + 0 + 10 
July 2016 = 0 + 0 + 0 + 10 
+0

vous pouvez faire cette question encore mieux en fournissant des données de jouets. Cela aide les gens à essayer rapidement leurs réponses avant de les poster. –

+0

S'il vous plaît vérifier [Comment faire de bons exemples de pandas reproductibles] (http://stackoverflow.com/questions/20109391/how-to-make-good-reproducible-pandas-examples) – jezrael

+0

Merci à tous les deux, j'ai ajouté quelques données et si ceux-ci ne fonctionne plus, j'ajouterai plus. – Tasos

Répondre

1

Je ne sais pas aucun moyen d'utiliser une boucle. Cependant, je peux suggérer un moyen de rendre le code assez propre et efficace.

D'abord, charger l'exemple des données que vous avez fournies dans le texte de la question:

df = pd.DataFrame({'date': ['01-01-2016', '05-01-2016', '10-01-2016','04-02-2016'], 
        'months': [1, 3, 1, 6], 
        'price': [40, 60, 20, 60]}) 

Pour utiliser la fonctionnalité de date de Panda (par exemple le regroupement par mois), nous allons utiliser la colonne date comme index. Un DateTimeIndex en fait:

df['date'] = pd.to_datetime(df['date'], format='%d-%m-%Y') 
df = df.set_index('date') 

Maintenant, il est vraiment facile, par exemple, afficher un résumé mois par mois, en utilisant la fonction resample qui fonctionne comme la fonction groupby vous le savez déjà, mais utilise de temps périodes:

df.resample('M').sum() 

maintenant, pour « Etalez » lignes où la colonne est months> 1 sur plusieurs mois.Mon approche est ici de générer une nouvelle DataFrame pour chaque ligne:

dfs = [] 
for date, values in df.iterrows(): 
    months, price = values 
    dfs.append(
     pd.DataFrame(
      # Compute the price for each month, and repeat this value 
      data={'price': [price/months] * months}, 
      # The index is a date range for the requested number of months 
      index=pd.date_range(date, periods=months, freq='M') 
     ) 
    ) 

Maintenant, nous pouvons juste concaténer la liste des DataFrame s, Rééchantillonne mois et prendre la somme:

pd.concat(dfs).resample('M').sum() 

Sortie:

  price 
2016-01-31  80 
2016-02-29  30 
2016-03-31  30 
2016-04-30  10 
2016-05-31  10 
2016-06-30  10 
2016-07-31  10 

Voir http://pandas.pydata.org/pandas-docs/stable/timeseries.html pour toutes les choses cool peut faire en ce qui concerne le temps de Panda. Par exemple, pour produire exactement votre sortie désirée, vous pouvez le faire:

output.index = output.index.strftime('%B %Y') 

Quels sont les résultats de cette:

   price 
January 2016  80 
February 2016  30 
March 2016  30 
April 2016  10 
May 2016   10 
June 2016   10 
July 2016   10 
+0

alors, cela a-t-il fonctionné pour vous? –

+0

Essayé quelques fois, mais il retourne toujours une seule valeur et non une base de données avec les mois et la somme des prix. – Tasos