您可以使用pd.isnull找到null – 在这种情况下为无 – 值:
In [169]: pd.isnull(df)
Out[169]:
first second third
0 False False False
1 True False False
2 True True False
3 True True True
4 False True False
然后使用np.argmin找到第一个非空值的索引.如果所有值都为空,则np.argmin返回0:
In [186]: np.argmin(pd.isnull(df).values,axis=1)
Out[186]: array([0,1,2,0])
然后可以使用NumPy整数索引从df中选择所需的值:
In [193]: df.values[np.arange(len(df)),np.argmin(pd.isnull(df).values,axis=1)]
Out[193]: array(['A','C','B',None,'A'],dtype=object)
例如,
import pandas as pd
df = pd.DataFrame([{'third':'B','second':None}])
mask = pd.isnull(df).values
df['combo1'] = df.values[np.arange(len(df)),np.argmin(mask,axis=1)]
order = np.array([1,0])
mask = mask[:,order]
df['combo2'] = df.values[np.arange(len(df)),order[np.argmin(mask,axis=1)]]
产量
first second third combo1 combo2
0 A C B A C
1 None C B C C
2 None None B B B
3 None None None None None
4 A None B A B
如果DataFrame有很多行,则使用argmin而不是df3.apply(coalesce,…)显着更快:
df2 = pd.concat([df]*1000)
In [230]: %timeit mask = pd.isnull(df2).values; df2.values[np.arange(len(df2)),axis=1)]
1000 loops,best of 3: 617 µs per loop
In [231]: %timeit df2.apply(coalesce,axis=1)
10 loops,best of 3: 84.1 ms per loop