For and while loop outputting longer list than it should

Viewed 44

I am trying to create an array of numbers (socarray) that are between 0 and 100. The array is initiated with a single item (integer 50).

The number to append is soc and is initiated at 50. The value of soc changes conditional on the value of a prediction column in a dataframe (df['Pred']).

  • If df['Pred']>0 and soc < 100 then soc += 50 and is appended to socarray.
  • If df['Pred'] <0 and soc > 0 then soc -=50 and is appended to socarray
  • else we just append soc (without adding or substracting from the value).

My code is below. I am using For loop, a while loop and an If statements.

The range is set to iterate 10 times (the length of the dataframe). However, the output of the code is an array of length 82.

soc = 50
socarray = [50]


for i in range(1,10):
    
    counter = 1
    
    while counter < len(df):
        
        if (df.iloc[i]['Pred'] > 0) & (soc<100):
            soc += 50
            socarray.append(soc)
            counter += 1
            
        elif (df.iloc[i]['Pred'] < 0) & (soc>0):
            soc -= 50
            socarray.append(soc)
            counter += 1
            
        else:
            soc = soc
            socarray.append(soc)
            counter += 1
            

If I embed the array into the for loop it outputs an array length 10 but it doesn't follow the correct functionality (specifically it doesn't subtract 'soc -= 50' when it should do)

soc = 50


for i in range(1,len(df)):

        socarray = [50]

    
    counter = 1
    
    while counter < len(df):
        
        if (df.iloc[i]['Pred'] > 0) & (soc<100):
            soc += 50
            socarray.append(soc)
            counter += 1
            
        elif (df.iloc[i]['Pred MW'] < 0) & (soc>0):
            soc -= 50
            socarray.append(soc)
            counter += 1
            
        else:
            soc = soc
            socarray.append(soc)
            counter += 1

Can someone help me?

2 Answers

Your while loop is running 10 times. Once for each range in your for loop. So with 82 values your while loop is running ~8 times each for loop iteration.

In your second example your socarray is being filled by the last iteration of the for loop only since its initialized inside the loop.

Since I don't have the dataframe its hard to test. I'm thinking this can be accomplished without the inner while loop.

You need to run your "algorithm" 10 times so the for loop in range 10 should be enough.

Try removing the while loop and counter.

soc = 50
socarray = [50]


for i in range(1,10):


    if (df.iloc[i]['Pred'] > 0) & (soc<100):
        soc += 50
        socarray.append(soc)
        counter += 1
        
    elif (df.iloc[i]['Pred'] < 0) & (soc>0):
        soc -= 50
        socarray.append(soc)
        counter += 1
        
    else:
        soc = soc
        socarray.append(soc)
        counter += 1

Consider assigning a new data frame column based on range sum by conditions. Then convert the column to a 1-D array. Do note all arithmetic (i.e., +, -) and inequality (i.e., <, >) operators have been replaced with corresponding Pandas functions:

# ASSIGN NEW COLUMN AND FIRST ROW VALUE AS 50
df['soc'] = np.nan
df.loc[0, 'soc'] = 50

# RE-ASSIGN COLUMN BY ROW AND CONDITION
for i in range(len(df)):
   df.loc[i, 'soc'] = np.where((df.loc[i,'Pred'].gt(0)) & (df.loc[0:i,'soc'].sum().lt(100)), 
                               df.loc[0:i,'soc'].sum().add(50),
                               np.where((df.loc[i,'Pred'].lt(0)) & (df.loc[0:i,'soc'].gt(0)),
                                        df.loc[0:i,'soc'].sum().sub(50), 
                                        df.loc[0:i,'soc'].sum()
                               )
                      )

socarray = df['soc'].to_numpy()
Related