这是金融工具标识符的数据框
import pandas as pd
import numpy as np
df = pd.DataFrame([["ISIN1", "CUSIP1", "SEDOL1"],
["ISIN2", "CUSIP2", "SEDOL2"],
["ISIN3", "CUSIP3", "SEDOL3"],
["ISIN4", "CUSIP4", "SEDOL4"]],
columns=["ISIN", "CUSIP", "SEDOL"])
df
ISIN CUSIP SEDOL
0 ISIN1 CUSIP1 SEDOL1
1 ISIN2 CUSIP2 SEDOL2
2 ISIN3 CUSIP3 SEDOL3
3 ISIN4 CUSIP4 SEDOL4
想象一下,缺少几个条目
df.iloc[(1,1)] = np.nan
df.iloc[(1,2)] = np.nan
df.iloc[(2,0)] = np.nan
df.iloc[(3,0)] = np.nan
df.iloc[(3,1)] = np.nan
df
ISIN CUSIP SEDOL
0 ISIN1 CUSIP1 SEDOL3
1 ISIN2 NaN NaN
2 NaN CUSIP3 SEDOL3
3 NaN NaN SEDOL4
在列ID中,我想基于此层次结构捕获单个变量:如果缺少ISIN,则要填充CUSIP。如果还缺少CUSIP,我想填充SEDOL。
我尝试了这个嵌套的if语句:
def identifier(row):
if ~pd.isnull(row['ISIN']):
return row['ISIN']
elif pd.isnull(row['ISIN']) & ~pd.isnull(row['CUSIP']):
return row['CUSIP']
elif pd.isnull(row['ISIN']) & pd.isnull(row['CUSIP']) & ~pd.isnull(row['SEDOL']):
return row['SEDOL']
df['ID'] = df[['SEDOL', 'CUSIP', 'ISIN']].apply(identifier, axis=1)
最近2个条目在ID列中返回错误的输出。
ISIN CUSIP SEDOL ID
0 ISIN1 CUSIP1 SEDOL1 ISIN1
1 ISIN2 NaN NaN ISIN2
2 NaN CUSIP3 SEDOL3 NaN
3 NaN NaN SEDOL4 NaN
我的预期输出是这样:
ISIN CUSIP SEDOL ID
0 ISIN1 CUSIP1 SEDOL1 ISIN1
1 ISIN2 NaN NaN ISIN2
2 NaN CUSIP3 SEDOL3 CUSIP3
3 NaN NaN SEDOL4 SEDOL4
希望我已经很好地解释了。 请注意,“ ISIN”是一个字符串。我的代码中没有使用.isin函数。 预先谢谢你。
答案 0 :(得分:3)
通常,您可以使用elif
(详细介绍here和here)来实现np.select
逻辑。
在这种情况下,您可以使用lookup
+ notnull().idxmax
简洁地执行此操作,以查找每行中的第一个非空值。我添加了一个额外的NaN
行,以说明该如何处理。
df['ID'] = df.lookup(df.index, df.notnull().idxmax(1))
# ISIN CUSIP SEDOL ID
#0 ISIN1 CUSIP1 SEDOL1 ISIN1
#1 ISIN2 NaN NaN ISIN2
#2 NaN CUSIP3 SEDOL3 CUSIP3
#3 NaN NaN SEDOL4 SEDOL4
#4 NaN NaN NaN NaN
为解释您最初遇到的问题,将~
与pd.isnull
一起使用。
df['ISIN'].apply(lambda x: ~pd.isnull(x))
0 -1
1 -1
2 -2
3 -2
4 -2
Name: ISIN, dtype: int64
这些不是0
,因此它们的取值为True
,这意味着您在'ISIN'
列中的每一行。您应该使用pd.notnull
(not pd.isnull
也可以)而不是~pd.isnull
df['ISIN'].apply(lambda x: pd.notnull(x))
0 True
1 True
2 False
3 False
4 False
Name: ISIN, dtype: bool
答案 1 :(得分:1)
IIUC使用bfill
df['ID']=df.bfill(1).iloc[:,0]
df
Out[346]:
ISIN CUSIP SEDOL ID
0 ISIN1 CUSIP1 SEDOL3 ISIN1
1 ISIN2 NaN NaN ISIN2
2 NaN CUSIP3 SEDOL3 CUSIP3
3 NaN NaN SEDOL4 SEDOL4
答案 2 :(得分:1)
from functools import reduce
df.loc[:, 'ID'] = reduce(lambda c1, c2: c1.combine_first(c2), [df[c] for c in df])
Out[68]:
ISIN CUSIP SEDOL ID
0 ISIN1 CUSIP1 SEDOL1 ISIN1
1 ISIN2 NaN NaN ISIN2
2 NaN CUSIP3 SEDOL3 CUSIP3
3 NaN NaN SEDOL4 SEDOL4