Python function returns only the first value instead of a dataframe

浪子不回头ぞ 提交于 2021-02-05 08:35:59

问题


I have build a function where I append the returns of 5 portfolios to a dataframe which I want to return to a variable . When I run the commands within the function row by row(kind of debugging) I end upwith the variable 'folioReturn'(which is the one I want my script to return) having the right amount of values (e.x 5). But if I call the function, only the first value of the dataframe is returned. Does anyone know how I can get the whole dataframe ?


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)


回答1:


return statement must be after the for loop if you want whole list in your case during the first loop only the value is returned. just remove the return from for loop it will work fine.

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)



回答2:


You're basically exiting the function too early.

Here are two examples to make it simpler to follow along:

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]

In test we create a list-variable called lst, then inside of a for-loop, we overwrite lst with the current variable num and then immediately issue a return statement, which only returns 0 because it's the first entry in the for-loop.

In test2 we do the same thing in the start of the loop, however, instead of overwriting lst we instead use the method list.append() which adds the value of num to the already created list.

After we're then done with the whole for-loop, we then use the return statement to give back the variable lst which now contains all the values from 0 to 9.


EDIT: It seems I failed to address the actual problem in your code. There are two major errors:

  • You're exiting your for-loop using the return statement because it's inside of the for-loop. Fix the indentation, and that should be resolved.

  • Inside of your for-loop, you're overwriting folioReturn instead of appending the values calculated inside of the for-loop to it. Replace the variable folioReturn inside of the for-loop, and then after you've created the DataFrame, append that value to folioReturn.



来源:https://stackoverflow.com/questions/62153383/python-function-returns-only-the-first-value-instead-of-a-dataframe

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!