2
votes

Pandas Multiple "group by" et opérations sur les valeurs

A avoir un ensemble de données

ID    ID2    var1
 1      p      10
 1      r       5
 1      p       9
 2      p       7
 2      r       6
 2      r       7

Je dois certifier que dans chaque Nº ID la différence entre (la somme de var1 par "p") et (la somme de var1 par "r" ) est supérieur à 0. En d'autres termes, je dois regrouper par ID et appliquer des opérations arithmétiques entre les valeurs regroupées par ID2. Merci pour vos suggestions


2 commentaires

Je pense que vous devriez clarifier un peu plus la question. Voulez-vous simplement "Grouper par" ou vous souhaitez effectuer des opérations arithmétiques entre les colonnes et grouper par en même temps?


Se mettre d'accord. Je vais expliquer ci-dessous


6 Réponses :


1
votes

Vous pouvez utiliser .groupby et .diff () pour calculer la différence après le groupby.

groupby = df.groupby(['ID', 'ID2']).var1.sum().diff().reset_index()

groupby['indicator'] = np.where(groupby.var1 > 0, 'yes', 'no')

print(groupby)
   ID ID2  var1 indicator
0   1   p   NaN        no
1   1   r -14.0        no
2   2   p   2.0       yes
3   2   r   6.0       yes

Vous pouvez également ajouter un indicateur, qui montre si la différence était supérieure à 0 avec np.where , avant cela, nous utilisons .reset_index pour récupérer notre colonne var1 .

df.groupby(['ID', 'ID2']).var1.sum().diff()

Out[72]: 
ID  ID2
1   p       NaN
    r     -14.0
2   p       2.0
    r       6.0
Name: var1, dtype: float64


1 commentaires

C'est une solution intéressante, mais échouerait s'il y avait d'autres valeurs dans var2 entre celles qui veulent être comparées.



1
votes

Je pense que vous avez besoin de

df.groupby(['ID','ID2']).sum().groupby(level=[0]).diff()
Out[174]: 
        var1
ID ID2      
1  p     NaN
   r   -14.0
2  p     NaN
   r     6.0


0 commentaires

2
votes
ID2   p   r  diff
ID               
1    19   5    14
2     7  13    -6

3 commentaires

Je pense que vous devez définir aggfunc = 'sum' sur votre table pivot_table. La fonction par défaut dans pivot_table est mean , l'O.P. a besoin de sum


Ajout de aggfunc = 'sum' comme noté par @Terry


Merci pour l'idée d'appliquer l'opérateur pivot. Je ne l'ai jamais utilisé chez les pandas! Bon à savoir. Génial



0
votes

Vos données:

    pd.crosstab(df.ID, [df.ID2,df.var1])

    ID2   p        r      
    var1  7  9  10 5  6  7 
    ID                    
    1     0  1  1  1  0  0
    2     1  0  0  0  1  1

Vous pouvez faire un tableau croisé:

    df=pd.crosstab(df.ID, [df.ID2,df.var1], margins=True)

    >>>df

    ID2   p        r       All
    var1  7  9 10  5  6  7    
    ID                        
    1     0  1  1  1  0  0   3
    2     1  0  0  0  1  1   3
    All   1  1  1  1  1  1   6

Sans marges:

    import pandas as pd
    df=pd.DataFrame([[1,'p',10], [1,'r',5], [1,'p',9 ],
                        [2,'p',7 ], [2,'r',6 ], [2,'r',7 ]], 
                        columns=['ID', 'ID2', 'var1'])


0 commentaires

0
votes

Merci beaucoup pour toutes vos suggestions! Je suis presque là...:) J'essayais tous les codes. Je pense que je n'ai pas été clair en expliquant ce que je veux en sortie. Je pense que pour le cas pratique sur lequel je travaille, il serait utile d'ajouter une ou deux variables supplémentaires dans la liste d'origine comme celle-ci (ci-dessous). Cela me permet de prendre des décisions concernant les identifiants avec des différences négatives dans les étapes suivantes.

 output:
 ID    ID2    var1   var2(diff)   var_control
 1      p      10          14              0
 1      r       5          14              0
 1      p       9          14              0
 2      p       7          -6              1
 2      r       6          -6              1
 2      r       7          -6              1


0 commentaires

0
votes

Je pense que je l'ai fait avec toute votre aide. Merci beaucoup! Vous êtes génial

import pandas as pd
import numpy as np

df = pd.DataFrame({'id': [23, 23, 23, 43, 43],
                   'id2': ["r", "p", "p", "p", "r"],
                   'var1': [4, 6, 7, 1, 3]})

print(df)

df2 = df.pivot_table(values = "var1", index="id", columns="id2", aggfunc='sum')
df2['diff'] = df2['p'] - df2['r']

df["var_2"]=df['id'].map(df2["diff"])

df['control'] = np.where(df['var_2']<0, 1, 0)


0 commentaires