Первая идея - использовать GroupBy.last
лямбда-функция intead:
df['col21'] = df['col1'].groupby(np.arange(len(df))//3).transform('last')
Если все еще необходимо улучшить производительность, используйте numpy
решение с np.repeat
:
arr = df['col1'].to_numpy()
arr1 = np.repeat(arr[2::3], 3)
lenght = len(arr) % 3
arr2 = np.repeat(arr[-1:], lenght)
df['col22'] = np.concatenate([arr1, arr2]).astype(int)
print (df)
col1 col21 col22
0 1 3 3
1 2 3 3
2 3 3 3
3 4 6 6
4 5 6 6
5 6 6 6
6 7 7 7
Производительность :
#[70000 rows x 1 columns]
df = pd.concat([df] * 10000, ignore_index=True)
In [122]: %%timeit
...: df['col20'] = df['col1'].groupby(np.arange(len(df))//3).transform(lambda x: x.iloc[-1])
...:
7.61 s ± 356 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
In [123]: %%timeit
...: df['col21'] = df['col1'].groupby(np.arange(len(df))//3).transform('last')
...:
...:
7.28 ms ± 103 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
In [124]: %%timeit
...: arr = df['col1'].to_numpy()
...: arr1 = np.repeat(arr[2::3], 3)
...: lenght = len(arr) % 3
...: arr2 = np.repeat(arr[-1:], lenght)
...: df['col22'] = np.concatenate([arr1, arr2]).astype(int)
...:
850 µs ± 18.9 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)