J'essaie de créer un compteur pour suivre le nombre d'échecs et de succès concernant plusieurs utilisateurs différents. J'ai un dataframe avec des codes utilisateurs qui se répètent (s'il y a plus d'événements sur les mêmes utilisateurs) et un horodatage pour suivre la variable de temps. J'aimerais ajouter deux colonnes (# de succès, # d'échecs) qui cumulent le résultat des événements précédents.
Exemple de données:
data=pd.DataFrame( { 'user_id': [2,2,3,2,4,5,3,3,6,6,6,7], 'timestamp': [1567641600,1567691600,1567741600,1567941600, 1567981600, 1567991600,1568391600,1568541600,1568741600,1568941600,1568981600,1568988600], 'status': ['yes','no','yes','no', 'yes', 'yes','yes','no','no','yes','no','yes'], 'number_yes':[1,1,1,1,1,1,2,2,0,1,1,1], 'number_no':[0,1,0,2,0,0,0,1,1,1,2,0] } )
J'ai essayé avec quelques boucles en R mais j'ai peur de manquer quelque chose, peut-être y a-t-il une meilleure façon de faire cela en Python?
Le résultat souhaité serait quelque chose comme ceci:
data=pd.DataFrame( { 'user_id': [2,2,3,2,4,5,3,3,6,6,6,7], 'timestamp': [1567641600,1567691600,1567741600,1567941600, 1567981600, 1567991600,1568391600,1568541600,1568741600,1568941600,1568981600,1568988600], 'status': ['yes','no','yes','no', 'yes', 'yes','yes','no','no','yes','no','yes'] } )
3 Réponses :
Utilisez la série . eq
pour créer un masque booléen, puis utilisez Series.groupby
, sur ce masque et transformez la série groupée en utilisant .cumsum
:
# print(data) user_id timestamp status number_yes number_no 0 2 1567641600 yes 1.0 0.0 1 2 1567691600 no 1.0 1.0 2 3 1567741600 yes 1.0 0.0 3 2 1567941600 no 1.0 2.0 4 4 1567981600 yes 1.0 0.0 5 5 1567991600 yes 1.0 0.0 6 3 1568391600 yes 2.0 0.0 7 3 1568541600 no 2.0 1.0 8 6 1568741600 no 0.0 1.0 9 6 1568941600 yes 1.0 1.0 10 6 1568981600 no 1.0 2.0 11 7 1568988600 yes 1.0 0.0
m = data['status'].eq('yes') data = data.assign( number_yes=m.groupby(data['user_id']).cumsum(), number_no=(~m).groupby(data['user_id']).cumsum() )
user_id timestamp status number_yes number_no 0 2 1567641600 yes 1 0 1 2 1567691600 no 1 1 2 3 1567741600 yes 1 0 3 2 1567941600 no 1 2 4 4 1567981600 yes 1 0 5 5 1567991600 yes 1 0 6 3 1568391600 yes 2 0 7 3 1568541600 no 2 1 8 6 1568741600 no 0 1 9 6 1568941600 yes 1 1 10 6 1568981600 no 1 2 11 7 1568988600 yes 1 0
Utilisons get_dummies
:
user_id timestamp status Number_maybe Number_no Number_yes 0 2 1567641600 yes 0 0 1 1 2 1567691600 no 0 1 1 2 3 1567741600 yes 0 0 1 3 2 1567941600 no 0 2 1 4 4 1567981600 maybe 1 0 0 5 5 1567991600 yes 0 0 1 6 3 1568391600 yes 0 0 2 7 3 1568541600 no 0 1 2 8 6 1568741600 maybe 1 0 0 9 6 1568941600 yes 1 0 1 10 6 1568981600 no 1 1 1 11 7 1568988600 yes 0 0 1
Output:
data=pd.DataFrame( { 'user_id': [2,2,3,2,4,5,3,3,6,6,6,7], 'timestamp': [1567641600,1567691600,1567741600,1567941600, 1567981600, 1567991600,1568391600,1568541600,1568741600,1568941600,1568981600,1568988600], 'status': ['yes','no','yes','no', 'maybe', 'yes','yes','no','maybe','yes','no','yes'] }) data.join(data['status'].str.get_dummies() .groupby(data['user_id']).cumsum() .add_prefix('Number_'))
Ce que j'aime dans l'utilisation de str.get_dummies
est que cela traitera plus que simplement «oui» et «non», insérons un nouveau statut «peut-être»:
user_id timestamp status Number_no Number_yes 0 2 1567641600 yes 0 1 1 2 1567691600 no 1 1 2 3 1567741600 yes 0 1 3 2 1567941600 no 2 1 4 4 1567981600 yes 0 1 5 5 1567991600 yes 0 1 6 3 1568391600 yes 0 2 7 3 1568541600 no 1 2 8 6 1568741600 no 1 0 9 6 1568941600 yes 1 1 10 6 1568981600 no 2 1 11 7 1568988600 yes 0 1
Résultat:
data.join(data['status'].str.get_dummies() .groupby(data['user_id']).cumsum() .add_prefix('Number_'))
Bonne utilisation de get_dummies
.
Génial, toutes les réponses étaient appropriées mais c'est vraiment une belle, merci.