Используйте groupby
с индексом с делением по полу и получите последние 3
строки на tail
:
df = df.groupby(df.index // 5).tail(3)
print(df)
a
2 2
3 3
4 4
7 7
8 8
9 9
12 12
13 13
14 14
15 15 <- last group have only one value, so tail select it
Другая идея - получить индексзначения каждой строки на np.arange
с изменением формы на 2d массив, выберите последние «столбцы» и сгладьте на ravel
, получите пересечение с реальными значениями индекса и выберите с помощью loc
:
N = 5
M = 3
pos = np.arange((len(df) // N + 1) * N).reshape(-1, N)[:, -M:].ravel()
idx = np.intersect1d(df.index, pos)
df = df.loc[idx]
print(df)
a
2 2
3 3
4 4
7 7
8 8
9 9
12 12
13 13
14 14
Деталь :
print(np.arange((len(df) // N + 1) * N).reshape(-1, N))
[[ 0 1 2 3 4]
[ 5 6 7 8 9]
[10 11 12 13 14]
[15 16 17 18 19]]
print (np.arange((len(df) // N + 1) * N).reshape(-1, N)[:, -M:])
[[ 2 3 4]
[ 7 8 9]
[12 13 14]
[17 18 19]]
print (np.arange((len(df) // N + 1) * N).reshape(-1, N)[:, -M:].ravel())
[ 2 3 4 7 8 9 12 13 14 17 18 19]
print(np.intersect1d(df.index, pos))
[ 2 3 4 7 8 9 12 13 14]