根据其他列的if-else填充pandas DataFrame的新列

时间:2019-05-13 23:07:01

标签: python pandas numpy dataframe

我遇到一种情况,我想在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']

3 个答案:

答案 0 :(得分:1)

方法1 fillna

在这种情况下,我们可以简单地将fillna上的col2col1中的值一起使用:

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

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

方法2 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

答案 1 :(得分:0)

尝试一下:

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 :(得分:0)

df.ffill上使用axis=1

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