Getting "IndexError: iloc cannot enlarge its target object" while trying to update a cell in a dataframe

5.7k views Asked by At

I am trying to calculate the running total and interest accrued for an account over a period of time. Running total is the sum of free cash on a day plus the interest accrued on the previous day

I am trying to update the columns running total (column 'Running_Tot') and interest accrued (column 'Interest_accr') for a dataframe within a for loop designed with iterrow(). But it appears that this update is actually trying to create new columns in the dataframe and since iloc doesn't allow the target object to be expanded it is throwing an error.

I observed that I could use .iloc outside of for - iterrow() loop without any error (Ex - df3.iloc[0, df3.columns.get_loc('Running_Tot')] = df3.iloc[0, df3.columns.get_loc('free_cash')]) but when I try to do something similar in for-iterrow() loop I get IndexError (Ex- df3.iloc[index, df3.columns.get_loc('Running_Tot')] = runtot).

Could you help me understand how I can update the values of a column in the iterrow() and not create new column in the process?

Thank you!

df3 = df_cash[df_cash['acct_num'] == '12345678']
df3.sort_values(['cal_date'], axis=0, ascending = True, inplace=True)
df3.iloc[0, df3.columns.get_loc('Running_Tot')] = df3.iloc[0, df3.columns.get_loc('free_cash')]
intaccr = 0

for index, row in df3.iterrows():
    runtot = row['free_cash'] + intaccr
    intaccr = row['Running_Tot'] * (row['bdp_rate'] / (365 * 100))
    df3.iloc[index, df3.columns.get_loc('Running_Tot')] = runtot #this line is throwing error
    df3.iloc[index, df3.columns.get_loc('Interest_accr')] = intaccr

df3
1

There are 1 answers

0
Cairoknox On

Your error indicates that you are trying to assign a value to an out-of-bound index. Moreover, it says that iloc is not able to enlarge the DataFrame in that case. Using iterrows() implies that the 'index' value will take any arbitrary index set in your DataFrame. However, iloc can only be accessed with the 0 to length-1 index (and boolean arrays but irrelevant here).

For that you can use the enumerate function. Also, you can use .loc in your case which is also more flexible for DataFrame enlargement (even though you don't need it there).

This should work:

df3 = df_cash[df_cash['acct_num'] == '12345678']
df3.sort_values(['cal_date'], axis=0, ascending = True, inplace=True)
df3.loc[0, 'Running_Tot'] = df3.loc[0, 'free_cash']
intaccr = 0

for index, row in enumerate(df3):
    runtot = row['free_cash'] + intaccr
    intaccr = row['Running_Tot'] * (row['bdp_rate'] / (365 * 100))
    df3.loc[index, 'Running_Tot'] = runtot
    df3.loc[index, 'Interest_accr'] = intaccr

df3