J'ai des doublons de clients avec un statut différent car il y a une ligne pour chaque abonnement / produit client. Je veux générer un new_status pour le client et pour qu'il soit «annulé», chaque statut d'abonnement doit être «annulé» ensemble.

J'ai utilisé:

df['duplicated'] = df.groupby('customer', as_index=False)['customer'].cumcount()

Pour séparer chaque doublon dans un index pour indiquer les valeurs dupliquées

Customer | Status | new_status | duplicated
 X       |canceled|            | 0
 X       |canceled|            | 1
 X       |active  |            | 2
 Y       |canceled|            | 0
 A       |canceled|            | 0
 A       |canceled|            | 1
 B       |active  |            | 0
 B       |canceled|            | 1

Ainsi, j'aimerais utiliser .apply et / ou .loc pour générer:

Customer | Status | new_status | duplicated
 X       |canceled|            | 0
 X       |canceled|            | 1
 X       |active  |            | 2
 Y       |canceled|            | 0
 A       |canceled| canceled   | 0
 A       |canceled| canceled   | 1
 B       |active  |            | 0
 B       |canceled|            | 1
2
Ricardo Fernandes 19 mars 2019 à 13:47

2 réponses

Meilleure réponse

D'après ce que je comprends, vous pouvez essayer de faire:

df['new_status']=(df.groupby('Customer')['Status'].
  transform(lambda x: x.eq('canceled').all()).map({True:'cancelled'})).fillna(df.new_status)
print(df)

    Customer    Status new_status  duplicated
0   X         canceled             0         
1   X         canceled             1         
2   X         active               2         
3   Y         canceled  cancelled  0         
4   A         canceled  cancelled  0         
5   A         canceled  cancelled  1         
6   B         active               0         
7   B         canceled             1   

MODIFIER depuis o / p attendu a été changé:

df['new_status']=(df.groupby('Customer')['Status'].
             transform(lambda x: x.duplicated(keep=False)&(x.eq('canceled').all()))
                         .map({True:'cancelled',False:''}))
print(df)

  Customer    Status new_status  duplicated
0   X         canceled             0         
1   X         canceled             1         
2   X         active               2         
3   Y         canceled             0         
4   A         canceled  cancelled  0         
5   A         canceled  cancelled  1         
6   B         active               0         
7   B         canceled             1   
1
anky 19 mars 2019 à 12:55

Comparer la colonne par Series.eq pour == et utilisez GroupBy.transform avec GroupBy.all pour vérifier si toutes les valeurs sont Trues par groupes, puis comparer Customer par Series.duplicated avec keep=False pour renvoyer toutes les dupes. Dernière chaîne par bit à AND (&) et définition des valeurs par numpy.where :

m1 = df['Status'].eq('canceled').groupby(df['Customer']).transform('all')
m2 = df['Customer'].duplicated(keep=False)

df['new_status'] = np.where(m1 & m2, 'cancelled', '')
print (df)
  Customer    Status new_status  duplicated
0        X  canceled                      0
1        X  canceled                      1
2        X    active                      2
3        Y  canceled                      0
4        A  canceled  cancelled           0
5        A  canceled  cancelled           1
6        B    active                      0
7        B  canceled                      1
2
jezrael 19 mars 2019 à 11:09