Python 函数 returns 只有第一个值而不是数据帧

Python function returns only the first value instead of a dataframe

我构建了一个函数,我将 5 个投资组合的 return 附加到一个数据框,我想将其 return 附加到一个变量。当我 运行 函数中的命令逐行(一种调试)时,我最终得到变量 'folioReturn'(这是我希望我的脚本 return 的变量)具有正确的数量值(e.x 5)。但是如果我调用函数,只有数据帧的第一个值是 returned。有谁知道我怎样才能得到整个数据框?


def portfolioReturns (securities, quintilesNo, perReturns):
    '''
    this function receives 
    1)securities: array with the security names and values ** for the purpose of our work the names
    should already be sorted
    2)quintilesNo: the number of portfolios we want to create 
    3)perReturns: an array with the returns that will be used for performance measuremnt

    It returns an array with the returns for each portfolio

    '''

    # we calculate the number of securities per portfolio 
    stdFolioSize = np.divmod(securities.size, quintilesNo)[0] # we take the floor division
    folioReturn = [] # pd.DataFrame()
    # we create portfolios with equal number of securities except of the last one where we use all the remaining securities
    for k in range(0, quintilesNo, 1): # in folio list we store the name of the securities we must include in each portfolio
        if k < (quintilesNo - 1):           
            folioList = securities.index.get_level_values(1)[k * stdFolioSize : (k + 1) * stdFolioSize]

        else: # the last portfolio will also include the remainder securities 
            folioList = securities.index.get_level_values(1)[k * stdFolioSize : securities.size]

        # now that we have the list of the securities to be included in the folio, we use the table
        # with the periodical returns to check the performance. The portfolio we construct is equally weighted

        # first we drop one index(the first index of the country) and then we store all the periodical returns in one-array 
        perRetFinalTable = pd.DataFrame(perReturns.reset_index(level = 0, drop = True)).T  

        # using the list of the bonds we want to include in our portfolio we pick the bond returns and
        # we store them in one array. Then we calculate the folio return
        folio = perRetFinalTable[folioList]
        folioReturn = np.append(folioReturn, folio.sum(axis = 1) * (1 / folio.size))
        folioReturn = pd.DataFrame(folioReturn).T
        # folioReturn = pd.Series(folioReturn).T

        return (folioReturn)

return 语句必须在 for 循环之后,如果您希望在第一个循环期间在您的案例中使用整个列表,仅值是 returned。 只需从 for 循环中删除 return 它就可以正常工作。

def portfolioReturns (securities, quintilesNo, perReturns):
    '''
    this function receives 
    1)securities: array with the security names and values ** for the purpose of our work the names
    should already be sorted
    2)quintilesNo: the number of portfolios we want to create 
    3)perReturns: an array with the returns that will be used for performance measuremnt

    It returns an array with the returns for each portfolio

    '''

    # we calculate the number of securities per portfolio 
    stdFolioSize = np.divmod(securities.size, quintilesNo)[0] # we take the floor division
    folioReturn = [] # pd.DataFrame()
    # we create portfolios with equal number of securities except of the last one where we use all the remaining securities
    for k in range(0, quintilesNo, 1): # in folio list we store the name of the securities we must include in each portfolio
        if k < (quintilesNo - 1):           
            folioList = securities.index.get_level_values(1)[k * stdFolioSize : (k + 1) * stdFolioSize]

        else: # the last portfolio will also include the remainder securities 
            folioList = securities.index.get_level_values(1)[k * stdFolioSize : securities.size]

        # now that we have the list of the securities to be included in the folio, we use the table
        # with the periodical returns to check the performance. The portfolio we construct is equally weighted

        # first we drop one index(the first index of the country) and then we store all the periodical returns in one-array 
        perRetFinalTable = pd.DataFrame(perReturns.reset_index(level = 0, drop = True)).T  

        # using the list of the bonds we want to include in our portfolio we pick the bond returns and
        # we store them in one array. Then we calculate the folio return
        folio = perRetFinalTable[folioList]
        folioReturn = np.append(folioReturn, folio.sum(axis = 1) * (1 / folio.size))
        folioReturn = pd.DataFrame(folioReturn).T
        # folioReturn = pd.Series(folioReturn).T

    return (folioReturn)

你基本上太早退出了这个功能。

这里有两个例子,可以更容易理解:

def test():
    lst = []
    for num in range(10):
        lst = num
        return lst

def test2():
    lst = []
    for num in range(10):
        lst.append(num)
    return lst

print(test()) # Output: 0
print(test2()) # Output: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

test中,我们创建一个名为lst的列表变量,然后在for循环中,我们用当前变量num覆盖lst,然后立即发出一个 return 语句,它只是 returns 0 因为它是 for 循环中的第一个条目。

test2中,我们在循环开始时做同样的事情,但是,我们没有覆盖lst,而是使用方法list.append(),它添加了[=的值14=] 到已经创建的列表。

完成整个 for 循环后,我们使用 return 语句返回变量 lst,它现在包含 0 中的所有值至 9.


编辑:看来我没能解决您代码中的 实际 问题。主要有两个错误:

  • 您正在使用 return 语句退出 for 循环,因为它在 for 循环内部。修复缩进,应该可以解决

  • 在您的 for 循环内部,您正在覆盖 folioReturn 而不是将在 for 循环内部计算的值附加到它。替换 for 循环内的变量 folioReturn,然后在创建 DataFrame 后,将该值附加到 folioReturn.