Python 基于数据框架的金融建模

Python 基于数据框架的金融建模,python,pandas,dataframe,modeling,financial,Python,Pandas,Dataframe,Modeling,Financial,我主要通过熊猫建立了一个简单的DCF模型。基本上所有的计算都发生在一个数据帧中。我想找到一种更好的编码风格,因为模型变得更复杂,模型中添加了更多的变量。下面的例子可以说明我当前的编码风格——简单而直接 # some customized formulas def GrowthRate(): def BoundedVal() .... # some operations df['EBIT'] = df['revenue'] - df['costs'] df['NI'] = df['EBIT'] -

我主要通过熊猫建立了一个简单的DCF模型。基本上所有的计算都发生在一个数据帧中。我想找到一种更好的编码风格,因为模型变得更复杂,模型中添加了更多的变量。下面的例子可以说明我当前的编码风格——简单而直接

# some customized formulas
def GrowthRate():
def BoundedVal()
....
# some operations
df['EBIT'] = df['revenue'] - df['costs']
df['NI'] = df['EBIT'] - df['tax'] - df['interests']
df['margin'] = df['NI'] / df['revenue']
我循环计算所有年份的数值。现在,我在模型中添加了500多个变量,计算也变得更加复杂。我想为每个变量创建一个单独的def,并相应地更新主df。因此,上述代码将变为:

def EBIT(t):
    df['EBIT'][t] = df['revenue'][t] - df['costs'][t]
    #....some more ops
    return df['EBIT'][t]

def NI(t):
    df['NI'][t] = EBIT(t) - df['tax'][t] - df['interests'][t]
    #....some more ops
    return df['NI'][t]

def margin(t):
    if check_df_is_nan():
        df['margin'][t] = NI(t) - df['costs'][t]
        #....some more ops
        return df['margin'][t]
    else:
        return df['margin'][t]
如果其他函数调用,每个函数都能够1)计算结果并更新df 2)返回值

为了避免冗余计算(考虑是否多次调用了margin(t)),最好在每个def中添加一个“check if val have computed before”(检查val是否已在之前计算过)函数

我的问题:1)是否可以将if语句添加到一组def中?类似于上面的if条款。
2) 我有超过50个自定义def,因此主文件变得太长。我不能简单地将所有def移动到另一个文件并导入all,因为一些def还引用主文件中的数据帧。有什么建议吗?是否可以将df设置为全局变量,以便其他文件中的DEF能够修改和更新?

对于1,只需检查值是否为NaN即可

import pandas as pd
def EBIT(t):
    if pd.notnull(df['EBIT'][t]):
        return df['EBIT'][t]

    df['EBIT'][t] = df['revenue'][t] - df['costs'][t]
    ...
对于2,使用全局变量可能有效,但这是一种糟糕的方法。你应该尽可能避免使用它们

您应该做的是让每个函数将全局数据帧作为参数。然后可以传入要操作的数据帧

# in some other file
def EBIT(df, t):
    # logic goes here

# in the main file
import operations as op
# ...
op.EBIT(df, t)
enter code here

你是否考虑过立即使用T?应该快得多

谢谢Jezzamon。我需要使用inplaceupdate,所以我通常先创建所有列,然后用np.nan填充。只是想知道这是否是一种避免“if”语句的方法,但我会将“if”逻辑应用于所有def。再次感谢Jezzamon。对于1,我添加了额外的df参数,并将所有自定义函数移动到另一个文件中。对于2,该模型使用t-1结果计算年份t值,因此循环年份是唯一的解决方案。不用担心时间的消耗。完成所有计算只需1秒钟,因此在当前阶段,我更关心如何正确编码。@Timescape很乐意提供帮助!如果你认为答案是正确的,你可以把它标记为正确的,这样人们就会知道问题已经回答了