Pandas中的嵌套If语句

2024-10-01 15:31:39 发布

您现在位置:Python中文网/ 问答频道 /正文

以下是金融工具标识符的数据框架

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

在columnid中,我想基于这个层次结构捕获一个变量:如果缺少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函数。 先谢谢你。你知道吗


Tags: dfnpnanrowpdisnullisincusip
3条回答
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

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

一般来说,可以使用np.select实现elif逻辑,这在herehere中有详细说明。你知道吗

在这种情况下,您可以使用lookup+notnull().idxmax简洁地找到每行中的第一个非空值。我添加了一个额外的allNaN行来说明如何处理它。你知道吗

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.notnullnot 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

相关问题 更多 >

    热门问题