Home > OS >  Using the previous value of the loop to get previous position (n-1) instead each one giving Key Erro
Using the previous value of the loop to get previous position (n-1) instead each one giving Key Erro

Time:10-15

In Python I use a loop and in the 6th line from the end in the code attached ( Portfolio_1_4 = Portfolio_1_4 * SP1500DailyReturns.loc[n_short, 'S&P 1500 SUPER COMPOSITE - PRICE INDEX'] / SP1500DailyReturns.loc[str(Portfolio_1_4_Date_sell_short), 'S&P 1500 SUPER COMPOSITE - PRICE INDEX']) I get a Key Error. This error appears as for some dates information is not present in SP1500DailyReturns, so code cant get it for the calculation.

How could it be possible to modify my algorithm, so that when this line faces a key error, it takes the date from the previous position (n-1) in a loop?

For example date for a date, "n_short" is not present, and then the algorithm grabs data from date "n_short - 1" instead of data for a date "Portfolio_1_4_Date_sell_short" is not present and then the algorithm grabs data for the date "Portfolio_1_4_Date_sell_short -1".

Thank you!

   for n in dates: 
   n_short = n[:10]
   Date_Buy = pd.Timestamp(n) 
   Date_sell = Date_Buy   pd.Timedelta("30 days") 
   Date_buy_SP1500 = Date_sell
   Date_sell_SP1500 = Date_Buy
   if (Test_set.loc[n, '4_signals'] == 1):

     if (Portfolio_1_4_Date_sell < pd.Timestamp(Test_set.loc[n, 'feedTimestamp'])):
       Portfolio_1_4 = Portfolio_1_4 * Test_set.loc[n, 'Cumulative stock Returns over the 30 days after transaction  (22 working days)'] # For 5 days i will have to change to 5 days column later
       Test_set.loc[n, 'Portfolio_1_4'] = Portfolio_1_4
       Portfolio_1_4_Date_sell = Date_Buy   pd.Timedelta("30 days")
       Portfolio_1_4_Date_sell_short = Portfolio_1_4_Date_sell.strftime("%Y-%m-%d")
       Portfolio_2_4 = Portfolio_2_4
       Test_set.loc[n, 'Portfolio_2_4'] = Portfolio_2_4
       Portfolio_3_4 = Portfolio_3_4
       Test_set.loc[n, 'Portfolio_3_4'] = Portfolio_3_4

     else:
       Test_set.loc[n, 'Portfolio_1_4_allocation'] = 'Portfolio 1 is already allocated!'
       Test_set.loc[n, 'Portfolio_1_4'] = Portfolio_1_4
       if (Portfolio_2_4_Date_sell < pd.Timestamp(Test_set.loc[n, 'feedTimestamp'])):
         Portfolio_2_4 = Portfolio_2_4 * Test_set.loc[n, 'Cumulative stock Returns over the 30 days after transaction  (22 working days)'] # For 5 days i will have to change to 5 days column later
         Test_set.loc[n, 'Portfolio_2_4'] = Portfolio_2_4
         Portfolio_2_4_Date_sell = Date_Buy   pd.Timedelta("30 days")
         Portfolio_3_4 = Portfolio_3_4
         Test_set.loc[n, 'Portfolio_3_4'] = Portfolio_3_4

       else:
        Test_set.loc[n, 'Portfolio_2_4_allocation'] = 'Portfolio 1 and 2 are already allocated!'
        Test_set.loc[n, 'Portfolio_2_4'] = Portfolio_2_4
        if (Portfolio_3_4_Date_sell < pd.Timestamp(Test_set.loc[n, 'feedTimestamp'])):
          Portfolio_3_4 = Portfolio_3_4 * Test_set.loc[n, 'Cumulative stock Returns over the 30 days after transaction  (22 working days)'] # For 5 days i will have to change to 5 days column later
          Test_set.loc[n, 'Portfolio_3_4'] = Portfolio_3_4
          Portfolio_3_4_Date_sell = Date_Buy   pd.Timedelta("30 days")

        else:
          Test_set.loc[n, 'Portfolio_3_4_allocation'] = 'Portfolio 1, 2 and 3 are already allocated!'
          Test_set.loc[n, 'Portfolio_3_4'] = Portfolio_3_3

   else:
       Portfolio_1_4 = Portfolio_1_4 * SP1500DailyReturns.loc[n_short, 'S&P 1500 SUPER COMPOSITE - PRICE INDEX'] / SP1500DailyReturns.loc[Portfolio_1_4_Date_sell_short, 'S&P 1500 SUPER COMPOSITE - PRICE INDEX']
       Test_set.loc[n, 'Portfolio_1_4'] = Portfolio_1_4
       Portfolio_2_4 = Portfolio_2_4 
       Test_set.loc[n, 'Portfolio_2_4'] = Portfolio_2_4
       Portfolio_3_4 = Portfolio_3_4 
       Test_set.loc[n, 'Portfolio_3_4'] = Portfolio_3_4

CodePudding user response:

Firstly, see how to produce a minimal reproducible example.

You could do this via two methods. You could store the previous variable for reference in the next loop. Or you could use enumerate() to capture the index and use that to call the previous entry. Examples of both are below

# Storing previous loop
n_old = None    # Initialising
for n in dates():
    try:
        data = n[0]
    except KeyError:
        data = n_old[0]
    n_old = n

# Using enumerate
for ii, n in enumerate(dates):
    try:
        data = n[0]
    except KeyError:
        if ii == 0:
            data = None
        else:
            data = dates[ii-1][0]

CodePudding user response:

i think the best is to fill the gaps of your date column before processing. here is a numpy version of how to do it

import numpy as np
dates=np.array(['1996-03-20', '2021-07-31', '1998-08-15', '1972-10-03', '', '1987-08-15'], dtype='datetime64')
mask=np.isnat(dates)
rot_mask=np.hstack((mask[1:],mask[0]))
dates[mask]=dates[rot_mask]
print(dates)
>>> ['1996-03-20' '2021-07-31' '1998-08-15' '1972-10-03' '1972-10-03'
 '1987-08-15']

this example does not handle consecutive gaps but if you understand how it works it won't be a problem

  • Related