了解递归函数的输出

use*_*983 7 python recursion pandas

我试图obtainingparams递归运行该函数5次.然而,目前从我的程序输出如下,我却无法理解,为什么线32323232while的代码的端部线圈不被每组的后打印出来MATRIX,PARAMS,VALUES输出.

MATRIX [[ 1.          7.53869055  7.10409234 -0.2867544 ]
 [ 1.          7.53869055  7.10409234 -0.2867544 ]
 [ 1.          7.53869055  7.10409234 -0.2867544 ]
 ..., 
 [ 1.          0.43010753  0.43010753  0.09642396]]
PARAMS [  5.12077446   8.89859946 -10.26880411  -9.58965259]
VALUES [(0.5, 1.5, 206.59958540866882, array([  5.12077446,   8.89859946, -10.26880411,  -9.58965259]))]
MATRIX [[ 1.          3.14775472  2.54122406 -0.43709966]
 [ 1.          3.14775472  2.54122406 -0.43709966]
 [ 1.          3.14775472  2.54122406 -0.43709966]
 ...,
 [ 1.          0.25806447  0.25806428  0.07982733]]
PARAMS [ 4.90731466  4.41623398 -7.65250737 -6.01128351]
VALUES [(0.5, 1.5, 206.59958540866882, array([  5.12077446,   8.89859946, -10.26880411,  -9.58965259])), (0.7, 1.7, 206.46228694927203, array([ 4.90731466,  4.41623398, -7.65250737, -6.01128351]))]
Run Code Online (Sandbox Code Playgroud)

等等.df是一个Dataframe.

values = []

def counted(fn):
    def wrapper(*args, **kwargs):
        wrapper.called+= 1
        return fn(*args, **kwargs)
    wrapper.called= 0
    wrapper.__name__= fn.__name__
    return wrapper


@counted   
def obtainingparams(self, df, tau_1, tau_2, residuals):
        global values
        no_of_bonds = df.shape[0]         
        yields = df['coupon'].values

        matrix_of_params = np.empty(shape=[1, 4])

        months_to_maturity_matrix = df.months_to_maturity.values

        count = 0
        for x, value in np.ndenumerate(months_to_maturity_matrix):
            if count < months_to_maturity_matrix.shape[0]:
                months_to_maturity_array = months_to_maturity_matrix[count]
                years_to_maturity_array = months_to_maturity_array/12
                newrow = [1, ((1-np.exp(-years_to_maturity_array/tau_1))/years_to_maturity_array/tau_1), ((1-np.exp(-years_to_maturity_array/tau_1))/years_to_maturity_array/tau_1)-np.exp(-years_to_maturity_array/tau_1), ((1-np.exp(-years_to_maturity_array/tau_2))/years_to_maturity_array/tau_2)-np.exp(-years_to_maturity_array/tau_2)] 
                count = count + 1
                matrix_of_params = np.vstack([matrix_of_params, newrow])

        matrix_of_params = np.delete(matrix_of_params, (0), axis=0)  
        print('MATRIX', matrix_of_params)

        params = np.linalg.lstsq(matrix_of_params,yields)[0] 
        print('PARAMS', params)
        residuals = np.sqrt(((yields - matrix_of_params.dot(params))**2).sum())  
        tau_1 = tau_1 + 0.2 
        tau_2 = tau_2 + 0.2

        values.append((tau_1, tau_2, residuals, params))
        print('VALUES', values)

        while self.obtainingparams(df, tau_1, tau_2, residuals).called < 5:
            print('32323232')
            self.obtainingparams(df, tau_1, tau_2, residuals)
Run Code Online (Sandbox Code Playgroud)

编辑:调用obtainingparams哪个是BondClass类中的函数:

tau_1 = 0.3
tau_2 = 1.3
BOND_OBJECT = BondClass.GeneralBondClass(price, coupon, coupon_frequecy, face_value, monthstomaturity, issue_date) 
residuals = [0, 0, 0, 0, 0]
df1 = Exc.ExcelFileReader() #Read the Dataframe in from an Excel File
BOND_OBJECT.obtainingparams(df1, tau_1, tau_2, residuals)
Run Code Online (Sandbox Code Playgroud)

Dag*_*oms 0

while self.obtainingparams(df, tau_1, tau_2, residuals).called < 5:
    print('32323232')
    self.obtainingparams(df, tau_1, tau_2, residuals)
Run Code Online (Sandbox Code Playgroud)

我的第一直觉是必须self.obtainingparams().called打电话self.obtainingparams()才能获得.called财产。通过这种方式,您可以递归地调用该函数,但无法在调用该函数之前传递到 while 循环,这解释了缺少输出的原因。

我建议不要使用包含的变量来计算递归实例,而是使用封闭范围中的变量,该变量可以在每次调用时递增,并让基本情况检查该变量,return一旦它达到您想要的递归步骤数。

例子:

count = 0

def recurse():
    count += 1
    # Base case
    if count >= 5:
        return
    else:
        recurse()
Run Code Online (Sandbox Code Playgroud)

最后,您需要再看看这行代码实际上做了什么:

self.obtainingparams(df, tau_1, tau_2, residuals).called
Run Code Online (Sandbox Code Playgroud)

您的函数obtainingparams实际上并不返回值,而是说它返回了一个int. 该行确实会进行检查int.called,但int没有名为 的属性called。如果您想检查函数对象的属性,则需要检查self.obtainingparams.called,尽管在我看来,有更好的方法来完成您尝试使用此代码执行的操作。

  • 是的,此外,此代码尝试在调用“obtainingparams”的**结果**上查找“called”,而不是函数本身。因此,即使“obtainingparams”确实返回一个值,这也是行不通的——该值不会有“叫”属性。 (2认同)