多个条件不返回值的 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 的解决方案可能要好得多,尽管我没有对我们的解决方案进行基准测试。
我合并了三个具有多个 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 的解决方案可能要好得多,尽管我没有对我们的解决方案进行基准测试。