【问题标题】:fill new column of pandas DataFrame based on if-else of other columns根据其他列的 if-else 填充 pandas DataFrame 的新列
【发布时间】:2019-09-30 22:05:41
【问题描述】:

我有一种情况,我想在 Pandas DataFrame 中创建一个新列,并根据涉及其他 2 个列的条件填充它。在这个例子中:

import pandas as pd
import numpy as np

df = pd.DataFrame(np.array([['value1','value2'],['value',np.NaN],[np.NaN,np.NaN]]), columns=['col1','col2'])

我想创建一个新列,'new col',它包含 1)'col2' 中的值,如果它不是 NaN,2)'col1' 中的值,如果它不是 NaN,否则3) NaN

我正在使用 .apply() 尝试此功能,但它没有返回所需的结果

def singleval(row):
    if row['col2'] != np.NaN:
        val = row['col2']
    elif row['col1'] != np.NaN:
        val = row['col1']
    else:
        val = np.NaN
    return val

df['new col'] = df.apply(singleval,axis=1)

我希望 'new col' 中的值是 ['value2', 'value', 'nan']

【问题讨论】:

    标签: python pandas numpy dataframe


    【解决方案1】:

    试试这个:

    df['col3'] = df[['col1','col2']].stack().groupby(level=0).last()
    

    输出:

        col1    col2    col3
    0   value1  value2  value2
    1   value   nan     value
    2   nan     nan     nan
    

    【讨论】:

      【解决方案2】:

      方法一fillna

      在这种情况下,我们可以简单地在col2 上使用fillnacol1 中的值:

      df['new col'] = df['col2'].fillna(df['col1'])
      

           col1    col2 new col
      0  value1  value2  value2
      1   value     NaN   value
      2     NaN     NaN     NaN
      

      方法二np.select

      如果您有多个条件,请使用 np.select 传递条件列表并根据这些条件传递选项:

      conditions = [
          df['col2'].notnull(),
          df['col1'].notnull(),
      ]
      
      choices=[df['col2'], df['col1']]
      
      df['new col'] = np.select(conditions, choices, default=np.NaN)
      

           col1    col2 new col
      0  value1  value2  value2
      1   value     NaN   value
      2     NaN     NaN     NaN
      

      注意

      NaN 的数据框不正确,请改用此数据框进行测试:

      df = pd.DataFrame({'col1':['value1', 'value', np.NaN],
                         'col2':['value2', np.NaN, np.NaN]})
      

      编辑:为什么该功能不起作用?

      np.NaN == np.NaN 将返回 False
      np.NaN is np.NaN 将返回True

      请参阅this question 了解相关说明。

      所以要修复你的功能,你必须使用is not:

      def singleval(row):
          if row['col2'] is not np.NaN:
              val = row['col2']
          elif row['col1'] is not np.NaN:
              val = row['col1']
          else:
              val = np.NaN
          return val
      
      df['new col'] = df.apply(singleval, axis=1)
      

           col1    col2 new col
      0  value1  value2  value2
      1   value     NaN   value
      2     NaN     NaN     NaN
      

      【讨论】:

      • 努力想知道为什么你的 df 与我的 df 不同...没关系:看起来它与 np.array() 有关系
      • 也不确定,这也是一个很好的问题:)。 @laszlopanaflex
      • 感谢您的 2 个解决方案。是否可以解释为什么我原来的方法不起作用?我无法看到 if-elif-else 方法在哪里崩溃......
      • 添加了关于你的方法的解释@laszlopanaflex,顺便说一句,好问题!
      【解决方案3】:

      axis=1 上使用df.ffill

      df['new_col'] = df.ffill(1).col2
      
      Out[1318]:
           col1    col2 new_col
      0  value1  value2  value2
      1   value     NaN   value
      2     NaN     NaN     NaN
      

      【讨论】:

        猜你喜欢
        • 2020-11-14
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-04-25
        • 2019-06-15
        • 2020-02-04
        相关资源
        最近更新 更多