多个条件不返回值的 Numpy Select

Numpy Select with Multiple Conditions Not Returning Values

我合并了三个具有多个 email 列的数据框,然后重命名了这些列以便于编写脚本。我正在尝试根据条件创建一个主电子邮件列。如果填充 C,请使用 C。如果不是,并且填充了 B,请使用 B。如果不是,并且填充了 A,请使用 A。出于某种原因,如果 C 被填充,它只会填充主列。即使填充了 A,它也会返回空值。

dfs = [df_A, d365, df_C]
from functools import reduce
dfFinal = reduce(lambda left,right: pd.merge(left,right,on='leadId'), dfs)

import numpy as np
emailconditions = [
dfFinal['EmailC'] is not None,
(dfFinal['EmailC'] is None) & (dfFinal['EmailB'] is not None),
(dfFinal['EmailC'] is None) & (dfFinal['EmailB'] is None)]

emailvalues = [
dfFinal['EmailC'],
dfFinal['EmailB'],
dfFinal['EmailA']]

dfFinal['emailFinal'] = np.select(emailconditions, emailvalues)

尝试像这样设置 emailconditions

emailconditions = [
dfFinal['EmailC'].notna(),
dfFinal['EmailC'].isna() & dfFinal['EmailB'].notna(),
dfFinal['EmailC'].isna() & dfFinal['EmailB'].isna()]

重点是用notna()代替is not None,用isna()代替is None

这是一个替代解决方案,它以您想要的优先顺序从列中获取第一个真值:

In [3]: df
Out[3]:
      a     b     c
0     x     w  None
1  None     y  None
2     k  None     z

In [4]: order = ("c", "b", "a")

In [5]: df.apply(lambda row: next(row[col] for col in order if row[col]), axis=1)
Out[5]:
0    w
1    y
2    z
dtype: object

如果您预计行中的 none 列有一个值,那么您可能需要这样的东西:

def first_truthy(row, order):
    try:
        return next(row[col] for col in order if row[col])
    except StopIteration:
        return None

输出:

In [7]: df
Out[7]:
      a     b     c
0     x     w  None
1  None     y  None
2     k  None     z
3  None  None  None


In [8]: df.apply(lambda row: first_truthy(row, order), axis=1)
Out[8]:
0       w
1       y
2       z
3    None
dtype: object

并不是说这可能比布尔掩码慢,但(在我看来)更容易推理和调试,并且不需要额外依赖 numpy。如果您需要性能,@richardec 的解决方案可能要好得多,尽管我没有对我们的解决方案进行基准测试。