Get differencies per rows by DataFrame.diff, compare for 1 with DataFrame.eq, count Trues by sum and compare if greater or equal by Series.ge:
df1 = df[df.diff(axis=1).eq(1).sum(axis=1).ge(3)]
EDIT: You can count consecutive 1 of differencies by cumulative sum, then get maximal values and compare for greater or equal:
print (df)
num1 num2 num3 num4 num5 num6
0 1 2 4 5 8 9
1 3 7 8 9 10 11
2 9 13 21 22 23 24
3 5 8 11 17 21 24
df1 = df.diff(axis=1)
m = df1.eq(1)
b = m.cumsum(axis=1)
mask = b.sub(b.mask(m).ffill(axis=1).fillna(0)).max(axis=1).ge(3)
df2 = df[mask]
print (df2)
num1 num2 num3 num4 num5 num6
1 3 7 8 9 10 11
2 9 13 21 22 23 24
Details:
print (b.sub(b.mask(m).ffill(axis=1).fillna(0)))
num1 num2 num3 num4 num5 num6
0 0.0 1.0 0.0 1.0 0.0 1.0
1 0.0 0.0 1.0 2.0 3.0 4.0
2 0.0 0.0 0.0 1.0 2.0 3.0
3 0.0 0.0 0.0 0.0 0.0 0.0
Performance (best test in real data), but generally rolling here is bottleneck:
#40k rows
df = pd.concat([df] * 10000, ignore_index=True)
In [82]: %%timeit
...: df1 = df.diff(axis=1)
...: m = df1.eq(1)
...: b = m.cumsum(axis=1)
...: mask = b.sub(b.mask(m).ffill(axis=1).fillna(0)).max(axis=1).ge(3)
...: df[mask]
...:
...:
35.6 ms ± 475 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)
In [83]: %%timeit
...: df[df.diff(axis=1).eq(1).T.rolling(window=N).sum().ge(N).any()]
...:
2.79 s ± 63.6 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)