J'aimerais de l'aide pour créer une nouvelle colonne dans Pandas qui indique si quelque chose s'est passé avant ou après dans une séquence. J'ai inclus une description du problème et un petit échantillon de la base de données sous forme de dictionnaire ci-dessous.

Le dataframe est une liste d'interventions qui arrivent aux utilisateurs sous forme de "texte" ou d'"appel". Chaque rangée est une intervention. Ainsi, par exemple, User122 a eu deux appels puis un texte (indiqué dans la colonne de séquence).

J'aimerais une nouvelle colonne qui précise si une intervention s'est produite avant ou après la première instance d'un appel. Ainsi, pour user122, il y aurait trois lignes dans une nouvelle colonne, "text_after_call" qui serait une série de quelque chose comme "avant, avant, après", car la première instance d'un texte est dans la séquence 3, et appelle où séquence 1 et 2. Si un utilisateur n'a pas de texte ou d'appel associé, la valeur serait NaN.

Je pense que la solution impliquerait de créer une boucle à travers chaque utilisateur et de vérifier si la ligne avec la première instance de "texte" est supérieure ou inférieure à la séquence du dernier "appel", mais je ne sais pas comment faire cela.

Toute aide est appréciée et faites-moi savoir si je peux rendre cette question plus facile à répondre !

{'sequence': {0: 1.0,
  1: 2.0,
  2: 3.0,
  3: 1.0,
  4: 1.0,
  5: 2.0,
  6: 1.0,
  7: 2.0,
  8: 3.0},
 'text_or_call': 
 {0: call,
  1: call,
  2: text,
  3: text,
  4: text,
  5: nan,
  6: text,
  7: call,
  8: call},
 'user': {0: 'user122',
  1: 'user122',
  2: 'user122',
  3: 'user124',
  4: 'user125',
  5: 'user125',
  6: 'user126',
  7: 'user126',
  8: 'user126'}}
0
tom 16 nov. 2020 à 20:08

1 réponse

Meilleure réponse

Si nous voulons spécifier si texts sont avant ou après le premier call d'un utilisateur, nous devons d'abord trouver l'index du premier appel pour chaque user.

first_call_index = df.groupby(['user']).apply(lambda x: np.min((x.loc[x['text_or_call'] == 'call']).index))

Cela donne un dataframe contenant l'index du premier appel de chaque utilisateur. Nous pouvons merge cela avec notre dataframe d'origine sur user.

df_index = df.merge(first_call_index.reset_index().rename(columns={0:'first_call_index'}))

Ensuite, nous pouvons simplement comparer l'index de chaque ligne avec la valeur de la ligne first_call_index et tester si la ligne actuelle est un message text. Si l'index de la ligne actuelle est avant le first_call_index, nous définissons la valeur sur before, dans le cas contraire, nous définissons la valeur sur after.

df_index.loc[(df_index['first_call_index'] < df_index.index) & (df_index['text_or_call'] == 'text'), 'text_after_call'] = 'After'
df_index.loc[(df_index['first_call_index'] > df_index.index) & (df_index['text_or_call'] == 'text'), 'text_after_call'] = 'Before'

Résultat

sequence    text_or_call    user    first_call_index    text_after_call
0   1.0     call            user122     0.0             NaN
1   2.0     call            user122     0.0             NaN
2   3.0     text            user122     0.0             After
3   1.0     text            user124     NaN             NaN
4   1.0     text            user125     NaN             NaN
5   2.0     NaN             user125     NaN             NaN
6   1.0     text            user126     7.0             Before
7   2.0     call            user126     7.0             NaN
8   3.0     call            user126     7.0             NaN
1
Rik Kraan 17 nov. 2020 à 13:43