Iterate using previous rows

Viewed 118

How could I create a col2 using an iterative type of rule?

col2 = col1 + 0.1(col2's previous value). If there is no previous value (here in 20 Dec 2019), then col2 should equal col1

df
  date      col1   
2019-12-20   10      
2019-12-27   3       
2020-01-03   7

Expected Output

  date      col1  col2  
2019-12-20   10     10   (no previous value, so equal col1)
2019-12-27   3      4    (3+0.1*10)
2020-01-03   7      7.4  (7+0.1*4)
3 Answers

Use np.cumsum (inspired by the formula of @MustafaAydın)

p = 0.1 ** np.arange(len(df)-1, -1, -1)
df['col2'] = np.cumsum(p * df['col1']) / p
>>> df
         date  col1  col2
0  2019-12-20    10  10.0
1  2019-12-27     3   4.0
2  2020-01-03     7   7.4

With some math, we have:

col2_{n} = \sum_{j=1}^{n} col1_{j} * 0.1^{n-j}

This can be implemented with expanding.agg:

df["col2"] = (df.col1
                .expanding()
                .agg(lambda win: (0.1 ** np.arange(win.size) * win[::-1]).sum()))

where win is the ever expanding window that is passed and n in the formula above is its size, i.e., win.size and col1_{j} will be its elements,

to get

         date  col1  col2
0  2019-12-20    10  10.0
1  2019-12-27     3   4.0
2  2020-01-03     7   7.4

I would just create a new list, and iterate over col1 using a for loop of col1.

df = pd.DataFrame({'col1': {0: 10, 1: 3, 2: 7}})
col2 = []
for x in df.col1:
        if not len(col2):
            col2.append(x)
        else:
            col2.append(x+0.1*col2[-1])
df['col2'] = col2

There's likely other ways using df.shift()

Related