web-dev-qa-db-fra.com

Pandas: remplacer conditionnellement les valeurs en fonction des valeurs des autres colonnes

J'ai un dataframe (df) qui ressemble à ceci:

                    environment     event   
time                    
2017-04-28 13:08:22     NaN         add_rd  
2017-04-28 08:58:40     NaN         add_rd  
2017-05-03 07:59:35     test        add_env
2017-05-03 08:05:14     prod        add_env
...

Maintenant, mon objectif est pour chaque add_rd Dans la colonne event, la valeur NaN- associée dans la colonne environment doit être remplacée par une chaîne RD.

                    environment     event   
time                    
2017-04-28 13:08:22     RD          add_rd  
2017-04-28 08:58:40     RD          add_rd  
2017-05-03 07:59:35     test        add_env
2017-05-03 08:05:14     prod        add_env
...

Ce que j'ai fait jusqu'à présent

Je suis tombé sur df['environment'] = df['environment].fillna('RD') qui remplace tous les NaN (ce qui n'est pas ce que je cherche), pd.isnull(df['environment']) qui détecte les valeurs manquantes et np.where(df['environment'], x,y) qui semble être ce que je veux mais ne fonctionne pas. De plus, j'ai essayé ceci :

import pandas as pd

for env in df['environment']:
    if pd.isnull(env) and df['event'] == 'add_rd':
        env = 'RD'

Les index sont manquants ou une sorte d'itérateur pour accéder à la valeur équivalente dans la colonne event.
Et j'ai essayé ceci :

df['environment'] = np.where(pd.isnull(df['environment']), df['environment'] = 'RD', df['environment'])

SyntaxError: keyword can't be an expression

ce qui évidemment n'a pas fonctionné.

J'ai jeté un coup d'œil à plusieurs questions, mais je n'ai pas pu m'appuyer sur les suggestions des réponses. question de Blackquestion de Simonquestion de szliquestion de Jan Willems Tulp

Alors, comment puis-je remplacer une valeur dans une colonne basée sur les valeurs d'une autre colonne?

5
Martin Müsli

Maintenant, mon objectif est pour chaque add_rd dans la colonne d'événement, la valeur NaN associée dans la colonne d'environnement doit être remplacée par une chaîne RD.

Selon le commentaire de @ Zero, utilisez pd.DataFrame.loc et indexation booléenne:

df.loc[df['event'].eq('add_rd') & df['environment'].isnull(), 'environment'] = 'RD'
3
jpp

Vous pourriez envisager d'utiliser where :

df.environment.where((~df.environment.isnull()) & (df.event != 'add_rd'),
                     'RD', inplace=True)

Si la condition n'est pas remplie, les valeurs sont remplacées par le deuxième élément.

3
CT Zhu

si vous voulez remplacer simplement 'add_rd' par 'RD', cela peut vous être utile

keys_to_replace = {'add_rd':'RD','add_env':'simple'}
df['environment'] = df.groupby(['event'])['environment'].fillna(keys_to_replace['add_rd'])
df

production:

    environment event
0   RD          add_rd
1   RD          add_rd
2   test        add_env
3   prod        add_env

si vous avez de nombreuses valeurs à remplacer en fonction de l'événement, vous devrez peut-être suivre groupby avec les valeurs de colonne "événement"

keys_to_replace = {'add_rd':'RD','add_env':'simple'}
temp = df.groupby(['event']).apply(lambda x:  x['environment'].fillna(keys_to_replace[x['event'].values[0]]))
temp.index = temp.index.droplevel(0)
df['environment'] = temp.sort_index().values

production:

   environment  event
0   RD          add_rd
1   RD          add_rd
2   test        add_env
3   prod        add_env
0
Naga kiran

C'est ici:

 df['environment']=df['environment'].fillna('RD')
0
Herc01