J'ai ce Dataframe

df:
     payout  person1 person2      date    
1    300.0     LA       NaN     2012-02-01  
2    500.0     DO       NaN     2012-02-01  
3    600.0     DO       NaN     2012-02-01  
4    300.0     DO       NaN     2012-01-01  
5    500.0     DO       NaN     2012-01-01  
6    1000.0    DO       AL      2012-01-01  
7    800.0     DO       AL      2012-01-01 

Dans un Dataframe séparé, je dois additionner tous les paiements de chaque mois et année uniques pour chaque personne1 séparément. Ensuite, si person2 existe, je dois diviser le paiement (après chaque somme mensuelle) entre person1 et person2.
La sortie devrait ressembler à ceci :

df:
         person     date         sum 
    1    LA         2012-02-01    300.0 
    2    DO         2012-02-01    1100.0        
    3    DO         2012-01-01    1700.0
    4    AL         2012-01-01    900.0 
1
debugging XD 11 mars 2019 à 21:45

2 réponses

Meilleure réponse

Vous pouvez créer une colonne qui contient le bon montant à additionner s'il y a quelqu'un dans la colonne person2 avec np.where

df['payout_sum'] = np.where(df.person2.notnull(), df.payout/2., df.payout)

Ensuite, en utilisant concat, groupby et pd.Grouper, vous pouvez obtenir le résultat :

df_tot = (pd.concat([df[['date','person1','payout_sum']].rename(columns={'person1':'person'}),
                     df[['date','person2','payout_sum']].rename(columns={'person2':'person'})
                                                          .dropna()])\
            .groupby([pd.Grouper(key='date', freq='MS'),'person'])['payout_sum']
            .sum().reset_index())
print (df_tot)
        date person  payout_sum
0 2012-01-01     AL       900.0
1 2012-01-01     DA      1700.0
2 2012-02-01     DA      1100.0
3 2012-02-01     LA       300.0

L'intérêt de pd.Grouper avec 'MS' est qu'il sera rééchantillonné en début de mois, au cas où vous auriez un paiement sur plusieurs jours dans un mois.

1
Ben.T 11 mars 2019 à 19:44

Probablement pas aussi élégant, mais fonctionne pour ce cas :

m1=(df[df.person2.isna()].groupby([df.date.dt.date,'person1'])
   .payout.sum().reset_index().rename(columns={'person1':'person'}))

m2=df.dropna().groupby([df.date.dt.date,'person1','person2']).payout.mean().reset_index()

df_new=(m1.merge(m2.melt(['date','payout'],value_name='person').
          drop('variable',1),how='outer').groupby(['date','person'],as_index=False).sum())

print(df_new)

         date person  payout
0  2012-01-01     AL   900.0
1  2012-01-01     DA  1700.0
2  2012-02-01     DA  1100.0
3  2012-02-01     LA   300.0
2
anky 11 mars 2019 à 19:32