In [4]:
#    nums   b    result
# 0  20.0  1    20.0
# 1  22.0  0    0
# 2  30.0  1    0
# 3  29.1  1    0
# 4  20.0  0    0

import pandas as pd
import numpy as np

df = pd.DataFrame({
        "nums": [20, 22, 30, 29.1, 20],
        "b": [20, 22, 30, 29.1, 20],
    })

for i in range(10):
    df = pd.concat([df, df], ignore_index=True)

print(df)

def some_calc_func(prev_result, prev_num, current_b):
    if current_b == 1:
        return prev_result * prev_num / 2
    else:
        return prev_num + 17


      nums     b
0     20.0  20.0
1     22.0  22.0
2     30.0  30.0
3     29.1  29.1
4     20.0  20.0
...    ...   ...
5115  20.0  20.0
5116  22.0  22.0
5117  30.0  30.0
5118  29.1  29.1
5119  20.0  20.0

[5120 rows x 2 columns]

In [22]:
%%timeit
for index, row in df.iterrows():
        pass


228 ms ± 5.18 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

In [23]:
%%timeit
for row in df.itertuples():
    pass


4.54 ms ± 88.5 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

In [27]:
%%timeit
for prev_num, curren_b in zip(df['nums'], df.loc[1:, 'b'],df['nums'], df.loc[1:, 'b'],df['nums'], df.loc[1:, 'b'],df['nums'], df.loc[1:, 'b']):
    pass


3.72 ms ± 30.1 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

In [8]:
%%timeit
for i in range(1, len(df.index)):
    row = df.index[i]
    new_row = df.index[i - 1]  # get index of previous row for "nums" and "result"
    df.loc[row, 'result'] = some_calc_func(prev_result=df.loc[new_row, 'result'], prev_num=df.loc[new_row, 'nums'], \
                             current_b=df.loc[row, 'b'])


1.5 s ± 61.2 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

In [ ]: