如何在pandas中实现sql coalesce

时间:2017-04-03 06:18:02

标签: python pandas

我有一个像

这样的数据框
df = pd.DataFrame({"A":[1,2,np.nan],"B":[np.nan,10,np.nan], "C":[5,10,7]})
     A     B   C
0  1.0   NaN   5
1  2.0  10.0  10
2  NaN   NaN   7 

我想添加一个新列“D”。预期输出

     A     B   C    D
0  1.0   NaN   5    1.0
1  2.0  10.0  10    2.0
2  NaN   NaN   7    7.0

提前致谢!

5 个答案:

答案 0 :(得分:8)

另一种方法是按顺序用A,B,C明确填充D列。

df['D'] = np.nan
df['D'] = df.D.fillna(df.A).fillna(df.B).fillna(df.C)

答案 1 :(得分:6)

我认为您需要bfill选择iloc的第一列:

df['D'] = df.bfill(axis=1).iloc[:,0]
print (df)
     A     B   C    D
0  1.0   NaN   5  1.0
1  2.0  10.0  10  2.0
2  NaN   NaN   7  7.0

同样如下:

df['D'] = df.fillna(method='bfill',axis=1).iloc[:,0]
print (df)
     A     B   C    D
0  1.0   NaN   5  1.0
1  2.0  10.0  10  2.0
2  NaN   NaN   7  7.0

答案 2 :(得分:4)

选项1
pandas

df.assign(D=df.lookup(df.index, df.isnull().idxmin(1)))

     A     B   C    D
0  1.0   NaN   5  1.0
1  2.0  10.0  10  2.0
2  NaN   NaN   7  7.0

选项2
numpy

v = df.values
j = np.isnan(v).argmin(1)
df.assign(D=v[np.arange(len(v)), j])

     A     B   C    D
0  1.0   NaN   5  1.0
1  2.0  10.0  10  2.0
2  NaN   NaN   7  7.0

天真时间测试
over given data

enter image description here

覆盖更大的数据

enter image description here

答案 3 :(得分:2)

另一种方法是使用combine_first的{​​{1}}方法。以您的示例pd.Series

df

我们有

>>> import pandas as pd
>>> import numpy as np
>>> df = pd.DataFrame({"A":[1,2,np.nan],"B":[np.nan,10,np.nan], "C":[5,10,7]})
>>> df
     A     B   C
0  1.0   NaN   5
1  2.0  10.0  10
2  NaN   NaN   7

我们可以使用>>> df.A.combine_first(df.B).combine_first(df.C) 0 1.0 1 2.0 2 7.0 来抽象该模式以处理任意数量的列。

reduce

让我们将所有这些放到一个函数中。

>>> cols = [df[c] for c in df.columns]
>>> reduce(lambda acc, col: acc.combine_first(col), cols)
0    1.0
1    2.0
2    7.0
Name: A, dtype: float64

答案 4 :(得分:0)

Pandas中已经有一种用于Series的方法:

df['D'] = df['A'].combine_first(df['C'])

或者如果您要顺序查找值,则只需堆叠它们:

df['D'] = df['A'].combine_first(df['B']).combine_first(df['C'])

这将输出以下内容:

>>> df
     A     B   C    D
0  1.0   NaN   5  1.0
1  2.0  10.0  10  2.0
2  NaN   NaN   7  7.0