我只想選擇具有三個或更多連續值的行。
| 數字1 | num2 | num3 | num4 | num5 | 數字6 |
|---|---|---|---|---|---|
| 1 | 2 | 3 | 4 | 5 | 6 |
| 3 | 7 | 8 | 9 | 10 | 11 |
| 9 | 13 | 21 | 22 | 23 | 24 |
| 5 | 8 | 11 | 17 | 21 | 24 |
[結果]
| 數字1 | num2 | num3 | num4 | num5 | 數字6 |
|---|---|---|---|---|---|
| 1 | 2 | 3 | 4 | 5 | 6 |
| 3 | 7 | 8 | 9 | 10 | 11 |
| 9 | 13 | 21 | 22 | 23 | 24 |
有沒有使用 pandas 或 numpy 的簡單方法?
uj5u.com熱心網友回復:
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()]
輸出:
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
連續值的中間計數:
>>> 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
以前的錯誤答案(此 Q/A 中的每個人都很常見)
這只是計算連續值的數量,而不是如果它們都是連續的。例如 1-2-4-5-7-8 將連續計算 3 個,而它們并非都是連續的*
N = 3
df1 = df[df.diff(axis=1).eq(1).sum(axis=1).ge(N)]
uj5u.com熱心網友回復:
獲取每行的差異 by DataFrame.diff,比較1with DataFrame.eq,count Trues bysum并比較 if 大于或等于 by Series.ge:
df1 = df[df.diff(axis=1).eq(1).sum(axis=1).ge(3)]
編輯:您可以通過 計算連續1的差異cumulative sum,然后獲取最大值并比較更大或等于:
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
詳情:
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
性能(真實資料中的最佳測驗),但通常rolling這里是瓶頸:
#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)
uj5u.com熱心網友回復:
嘗試這個 :
df = df[df.diff(axis=1).eq(1).sum(axis=1).ge(3)]
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/447959.html
