了解递归函数的输出

时间:2015-07-27 15:37:51

标签: python recursion pandas

我试图以递归方式运行函数obtainingparams 5次。但是,目前我程序的输出如下,我实际上无法理解为什么代码末尾的32323232循环中的行while在每组之后都没有打印出来。 MATRIXPARAMSVALUES输出。

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]))]

等等。 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)

修改:调用obtainingparamsBondClass内的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)

{{1}}

2 个答案:

答案 0 :(得分:1)

问题是你永远不会进入while循环,因为为了输入它,你进行递归调用。因此,在评估called上的测试之前,您已经在递归。此代码不是您想要的:

while self.obtainingparams(df, tau_1, tau_2, residuals).called < 5:

它在函数调用的结果中查找called而不是函数本身。只需将其替换为:

while self.obtainingparams.called < 5:

你应该就在那里。

答案 1 :(得分:0)

while self.obtainingparams(df, tau_1, tau_2, residuals).called < 5:
    print('32323232')
    self.obtainingparams(df, tau_1, tau_2, residuals)

我的第一直觉是self.obtainingparams().called必须致电self.obtainingparams()才能获得.called财产。通过这种方式,您可以递归地调用函数,但在调用函数之前无法进入while循环,这说明缺少输出。

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

示例:

count = 0

def recurse():
    count += 1
    # Base case
    if count >= 5:
        return
    else:
        recurse()

最后,您需要再看看这行代码实际执行的操作:

self.obtainingparams(df, tau_1, tau_2, residuals).called

您的函数obtainingparams实际上并没有返回值,而是说它返回了int。这一行真的会检查int.called,但int没有名为called的属性。如果你想检查函数对象的属性,你可以检查self.obtainingparams.called,虽然在我看来有更好的方法可以做你正在尝试用这个代码做的事情。