pandas 如何在Python中对同一列应用多个函数?

qlvxas9a  于 2022-12-02  发布在  Python
关注(0)|答案(1)|浏览(209)

我需要帮助将下面的case语句函数一次或并行应用到同一列?不确定是否以最有效的方式进行,是否有其他方法可以实现?

#Accrued Calc for ACT/360
def bbb(bb):
    if bb["Basis"] == "ACT/360" and bb['Type'] == 'L' and bb['Current Filter'] == 'Current CF':
        return 1 * bb['Principal/GrossAmount'] * (bb['All in Rate']/100)* (bb['Number of days'])/360
    elif  bb["Basis"] == "ACT/360" and bb['Type'] == 'D':
        return -1 * bb['Principal/GrossAmount'] * (bb['All in Rate']/100)* (bb['Number of days'])/360
    else:
        return ''
kf['Accrued Calc'] = kf.apply(bbb, axis = 1)

#Accrued Calc for ACT/365
def ccc(cc):
    if cc["Basis"] == "ACT/365" and cc['Type'] == 'L' and cc['Current Filter'] == 'Current CF':
        return 1 * cc['Principal/GrossAmount'] * (cc['All in Rate']/100)* (cc['Number of days'])/365
    elif  cc["Basis"] == "ACT/365" and cc['Type'] == 'D':
        return -1 * cc['Principal/GrossAmount'] * (cc['All in Rate']/100)* (cc['Number of days'])/365
    else:
        return ''
kf['Accrued Calc'] = kf.apply(ccc, axis = 1)

#Accrued Calc for 30/360 Basis 
{def ppp(ll):
    if ll["Basis"] == "30/360" and ll['Type'] == 'L' and ll['Current Filter'] == 'Current CF':
        return 1 * ll['Principal/GrossAmount'] * (ll['All in Rate']/100)* (360 *(Settlement.year - ll['Start Date YEAR']) + 30 * (Settlement.month - ll['Start Date MONTH']) + Settlement.day - ll['Start Date DAYS'])/360
    elif  ll["Basis"] == "30/360" and ll['Type'] == 'D':
        return -1 * ll['Principal/GrossAmount'] * (ll['All in Rate']/100)* (360 *(Settlement.year - ll['Start Date YEAR']) + 30 * (Settlement.month - ll['Start Date MONTH']) + Settlement.day - ll['Start Date DAYS'])/360
    else:
        return ''
kf['Accrued Calc'] = kf.apply(ppp, axis = 1)}

我试过下面的

kf['Accrued Calc'] = kf['Accrued Calc'].apply(bbb) & kf['Accrued Calc'].apply(ccc) & kf['Accrued Calc'].apply(ppp)

不确定将所有函数都放在一个大函数下是否合适?

ffdz8vbo

ffdz8vbo1#

你应该有一个函数来决定要调用哪个函数。将该函数应用到你的 Dataframe 中。根据你的条件,这个函数可以调用正确的函数,其中包含你的计算内容。另外,为了可读性,请将你的函数和变量重命名为有意义的名称:

#Accrued Calc for ACT/360
def accrued_act_360(row):
    if row['Type'] == 'L' and row['Current Filter'] == 'Current CF':
        return 1 * row['Principal/GrossAmount'] * (row['All in Rate']/100)* (row['Number of days'])/360
    elif row['Type'] == 'D':
        return -1 * row['Principal/GrossAmount'] * (row['All in Rate']/100)* (row['Number of days'])/360
    else:
        return ''

#Accrued Calc for ACT/365
def accrued_act_365(row):
    if row['Type'] == 'L' and row['Current Filter'] == 'Current CF':
        return 1 * row['Principal/GrossAmount'] * (row['All in Rate']/100)* (row['Number of days'])/365
    elif row['Type'] == 'D':
        return -1 * row['Principal/GrossAmount'] * (row['All in Rate']/100)* (row['Number of days'])/365
    else:
        return ''

#Accrued Calc for 30/360 Basis 
def accrued_30_360(row):
    if row['Type'] == 'L' and row['Current Filter'] == 'Current CF':
        return 1 * row['Principal/GrossAmount'] * (row['All in Rate']/100)* (360 *(Settlement.year - row['Start Date YEAR']) + 30 * (Settlement.month - row['Start Date MONTH']) + Settlement.day - row['Start Date DAYS'])/360
    elif row['Type'] == 'D':
        return -1 * row['Principal/GrossAmount'] * (row['All in Rate']/100)* (360 *(Settlement.year - row['Start Date YEAR']) + 30 * (Settlement.month - row['Start Date MONTH']) + Settlement.day - row['Start Date DAYS'])/360
    else:
        return ''

def accrued_calc(row):
    if row["Basis"] == "ACT/360":
        return accrued_act_360(row)
    elif row["Basis"] == "ACT/365":
        return accrued_act_365(row)
    elif row["Basis"] == "30/360":
        return accrued_30_360(row)
    else:
        return ""

kf['Accrued Calc'] = kf.apply(accrued_calc, axis = 1)

**然而:**这种方法无法利用Pandas惊人的矢量化处理能力。

您可以使用布尔索引来确定哪些行满足特定条件,并且只为 * 整个 Dataframe * 一次性设置这些行,而不是逐行应用函数。

def accrued_act_360_vec(df):
    # Find which rows match your condition
    type_l_rows = (df["Basis"] == "ACT/360") & (df["Type"] == "L") & (df["Current Filter"] == "Current CF")

    # Set the value for those rows
    df.loc[type_l_rows, "Accrued Calc"] = df.loc[type_l_rows, 'Principal/GrossAmount'] * (df.loc[type_l_rows, 'All in Rate']/100)* (df.loc[type_l_rows, 'Number of days'])/360

    type_d_rows = (df["Basis"] == "ACT/360") & (df["Type"] == "D")
    df.loc[type_d_rows, "Accrued Calc"] = -1 * df.loc[type_d_rows, 'Principal/GrossAmount'] * (df.loc[type_d_rows, 'All in Rate']/100)* (df.loc[type_d_rows, 'Number of days'])/360

    # No need to consider the else condition: Those rows never get set.

def accrued_act_365_vec(df):
    type_l_rows = (df["Basis"] == "ACT/365") & (df['Type'] == 'L') & (df['Current Filter'] == 'Current CF')
    df.loc[type_l_rows, "Accrued Calc"] = 1 * df.loc[type_l_rows, 'Principal/GrossAmount'] * (df.loc[type_l_rows, 'All in Rate']/100)* (df.loc[type_l_rows, 'Number of days'])/365

    type_d_rows = (df["Basis"] == "ACT/365") & (df['Type'] == 'D')
    df.loc[type_d_rows, "Accrued Calc"] = -1 * df.loc[type_d_rows, 'Principal/GrossAmount'] * (df.loc[type_d_rows, 'All in Rate']/100)* (df.loc[type_d_rows, 'Number of days'])/365

def accrued_30_360_vec(df):
    type_l_rows = (df["Basis"] == "30/360") & (df['Type'] == 'L') & (df['Current Filter'] == 'Current CF')
    df.loc[type_l_rows, "Accrued Calc"] = 1 * df.loc[type_l_rows, 'Principal/GrossAmount'] * (df.loc[type_l_rows, 'All in Rate']/100)* (360 *(Settlement.year - df.loc[type_l_rows, 'Start Date YEAR']) + 30 * (Settlement.month - df.loc[type_l_rows, 'Start Date MONTH']) + Settlement.day - df.loc[type_l_rows, 'Start Date DAYS'])/360
    
    type_d_rows = (df["Basis"] == "30/360") & (df['Type'] == 'D')
    df.loc[type_d_rows, "Accrued Calc"] = -1 * df.loc[type_d_rows, 'Principal/GrossAmount'] * (df.loc[type_d_rows, 'All in Rate']/100)* (360 *(Settlement.year - df.loc[type_d_rows, 'Start Date YEAR']) + 30 * (Settlement.month - df.loc[type_d_rows, 'Start Date MONTH']) + Settlement.day - df.loc[type_d_rows, 'Start Date DAYS'])/360

请注意,这些函数包含df["Basis"] == ...的条件,因为它们都是独立函数。要运行这些函数,只需执行以下操作:

accrued_act_360_vec(kf)
accrued_act_365_vec(kf)
accrued_30_360_vec(kf)

请重新检查我的代码中公式的准确性,我可能在复制/粘贴过程中不小心把它们搞砸了

相关问题