【问题标题】:Pandas: Conditionally replace values based on other columns valuesPandas:根据其他列值有条件地替换值
【发布时间】:2019-02-12 21:38:52
【问题描述】:

我有一个如下所示的数据框 (df):

                    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
...

现在我的目标是对于event 列中的每个add_rdenvironment 列中关联的NaN-值应替换为字符串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
...

到目前为止我做了什么

我偶然发现 df['environment'] = df['environment].fillna('RD') 替换了 every NaN(这不是我想要的),pd.isnull(df['environment']) 正在检测缺失值和 np.where(df['environment'], x,y) 这似乎是什么我想要但不工作。 我还尝试过这个

import pandas as pd

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

索引丢失或某种迭代器无法访问event 列中的等效值。
我试过了

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

SyntaxError: keyword can't be an expression

这显然没有用。

我查看了几个问题,但无法以答案中的建议为基础。 Black's questionSimon's questionszli's questionJan Willems Tulp's question

那么,如何根据另一列的值替换一列中的值?

【问题讨论】:

  • 使用df.loc[df['environment'].isnull() & df['event'].eq('add_rd'), 'environment'] = 'RD'
  • 您的最后一次尝试非常接近 - 我认为您只需将其更改为 df['environment'] = np.where(pd.isnull(df['environment']), 'RD', df['environment'])
  • @ason​​gtoruin 我正式失明了 ;) ... 成功了!

标签: python python-3.x pandas dataframe


【解决方案1】:

使用 DataFrame.loc 替换特定列中的值

In [1]: import pandas as pd

In [2]: dictionary = {'time': ['2017-04-28 13:08:22', '2017-04-28 08:58:40', 
                               '2017-05-03 07:59:35','2017-05-03 08:05:14'],
                       'environment': ['NaN', 'NaN', 'test', 'prod'], 
                       'event': ['add_rd', 'add_rd', 'add_env', 'add_env']
                     }

In [3]: df = pd.DataFrame(dictionary, columns= ['time', 'environment', 'event'])
        print(df) 
        
Out [3]:                  time environment    event
         0  2017-04-28 13:08:22         NaN   add_rd
         1  2017-04-28 08:58:40         NaN   add_rd
         2  2017-05-03 07:59:35        test  add_env
         3  2017-05-03 08:05:14        prod  add_env

In [4]: df.loc[df['event'] == 'add_rd', 'environment'] = 'RD'
        print(df) 
        
Out [4]:                  time environment    event
         0  2017-04-28 13:08:22          RD   add_rd
         1  2017-04-28 08:58:40          RD   add_rd
         2  2017-05-03 07:59:35        test  add_env
         3  2017-05-03 08:05:14        prod  add_env

【讨论】:

    【解决方案2】:

    这里是:

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

    【讨论】:

    • “我偶然发现 df['environment'] = df['environment].fillna('RD') 替换了每个 NaN(这不是我想要的),”谢谢你贡献,但请阅读问题。我已经找到了这个
    【解决方案3】:

    你可以考虑使用where:

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

    如果不满足条件,则将值替换为第二个元素。

    【讨论】:

      【解决方案4】:

      现在我的目标是对于事件列中的每个 add_rd,关联的 环境列中的 NaN 值应替换为字符串 研发。

      根据@Zero 的评论,使用pd.DataFrame.loc 和布尔索引:

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

      【讨论】:

        【解决方案5】:

        如果您只想将 'add_rd' 替换为 'RD',这对您很有用

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

        输出:

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

        如果您有很多值要根据事件替换,那么您可能需要在 groupby 后面加上“事件”列值

        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
        

        输出:

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

        【讨论】:

        • 不需要这一切。我知道这个问题已经得到解答,但这可以通过一个简单的 fillna 来完成
        猜你喜欢
        • 2018-11-13
        • 2020-11-17
        • 1970-01-01
        • 1970-01-01
        • 2021-02-20
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多