获取每行的差异DataFrame.diff,比较1与DataFrame.eq,计数Trues bysum并比较是否大于或等于Series.ge:
df1 = df[df.diff(axis=1).eq(1).sum(axis=1).ge(3)]\nRun Code Online (Sandbox Code Playgroud)\n编辑:您可以1通过以下方式计算连续的差异cumulative sum,然后获取最大值并比较是否大于或等于:
print (df)\n num1 num2 num3 num4 num5 num6\n0 1 2 4 5 8 9\n1 3 7 8 9 10 11\n2 9 13 21 22 23 24\n3 5 8 11 17 21 24\n\ndf1 = df.diff(axis=1)\nm = df1.eq(1)\nb = m.cumsum(axis=1)\nmask = b.sub(b.mask(m).ffill(axis=1).fillna(0)).max(axis=1).ge(3)\ndf2 = df[mask]\nprint (df2)\n num1 num2 num3 num4 num5 num6\n1 3 7 8 9 10 11\n2 9 13 21 22 23 24\nRun Code Online (Sandbox Code Playgroud)\n细节:
\nprint (b.sub(b.mask(m).ffill(axis=1).fillna(0)))\n num1 num2 num3 num4 num5 num6\n0 0.0 1.0 0.0 1.0 0.0 1.0\n1 0.0 0.0 1.0 2.0 3.0 4.0\n2 0.0 0.0 0.0 1.0 2.0 3.0\n3 0.0 0.0 0.0 0.0 0.0 0.0\nRun Code Online (Sandbox Code Playgroud)\n性能(真实数据中的最佳测试),但一般来说rolling这里是瓶颈:
#40k rows\ndf = pd.concat([df] * 10000, ignore_index=True)\n\nIn [82]: %%timeit\n ...: df1 = df.diff(axis=1)\n ...: m = df1.eq(1)\n ...: b = m.cumsum(axis=1)\n ...: mask = b.sub(b.mask(m).ffill(axis=1).fillna(0)).max(axis=1).ge(3)\n ...: df[mask]\n ...: \n ...: \n35.6 ms \xc2\xb1 475 \xc2\xb5s per loop (mean \xc2\xb1 std. dev. of 7 runs, 10 loops each)\n\n\nIn [83]: %%timeit\n ...: df[df.diff(axis=1).eq(1).T.rolling(window=N).sum().ge(N).any()]\n ...: \n2.79 s \xc2\xb1 63.6 ms per loop (mean \xc2\xb1 std. dev. of 7 runs, 1 loop each)\nRun Code Online (Sandbox Code Playgroud)\n
IIUC,计算diff列上的 a,选择等于 1 的值(即连续值)(带有eq),并确定是否存在 3 个连续值rolling.sum。使用生成的 Series 执行布尔索引:
N=3
df[df.diff(axis=1).eq(1).T.rolling(window=N).sum().ge(N).any()]
Run Code Online (Sandbox Code Playgroud)
输出:
num1 num2 num3 num4 num5 num6
0 1 2 3 4 5 6
1 3 7 8 9 10 11
2 9 13 21 22 23 24
Run Code Online (Sandbox Code Playgroud)
连续值的中间计数:
>>> df.diff(axis=1).eq(1).T.rolling(window=3).sum()
0 1 2 3
num1 NaN NaN NaN NaN
num2 NaN NaN NaN NaN
num3 2.0 1.0 0.0 0.0
num4 3.0 2.0 1.0 0.0
num5 3.0 3.0 2.0 0.0
num6 3.0 3.0 3.0 0.0
Run Code Online (Sandbox Code Playgroud)
这仅计算连续值的数量,而不计算它们是否都是连续的。例如 1-2-4-5-7-8 将算作 3 个连续的,但它们并不都是连续的*
N = 3
df1 = df[df.diff(axis=1).eq(1).sum(axis=1).ge(N)]
Run Code Online (Sandbox Code Playgroud)