发布this时,我应该问以下问题。如下所示,我的df
包含一些相同的连续值,即1、2和3。
Date London Paris Dubai Tokyo
18/07/2017 22:35 1 2406 4348 70715
18/07/2017 22:40 1 4756 3744 3
18/07/2017 22:45 1 3988 2915 3
18/07/2017 22:50 2280 3058 2120 3
18/07/2017 22:55 2 1 1939 3
18/07/2017 23:00 2 1 2256 3
18/07/2017 23:05 2121 1 2640 2025
18/07/2017 23:10 3367 2 2202 1916
18/07/2017 23:15 3247 3 1 2
18/07/2017 23:20 2491 3 1 2
18/07/2017 23:25 2010 3 1 1560
18/07/2017 23:30 1899 3 1366 1355
18/07/2017 23:35 1992 2265 1236 1
18/07/2017 23:40 2196 4407 2 1
18/07/2017 23:45 1961 3848 2 1
18/07/2017 23:50 3 2880 2809 4565
18/07/2017 23:55 3 2143 2397 3725
19/07/2017 00:00 3 1981 3 2921
19/07/2017 00:05 3 2227 3 2131
19/07/2017 00:10 1366 2526 3 1990
我想检测这些“死值”,只要它们停留在最少3行中,然后用NaN更改它们,因为我想在以后消除它们。使用here中的代码,我可以在London列中使用它。
g = df.London.diff().fillna(0).ne(0).cumsum()
m = df.groupby(g).London.transform('size').ge(3)
df.loc[m,'London'] = np.nan
df.assign(grouper=g, mask=m, result=df.London)
但是,我也想对其他人(大约250列)做同样的事情。
以下是预期的输出,其中所有1和3都转换为NaN,因为它们的值至少停留3个连续行。
Date London Paris Dubai Tokyo
18/07/2017 22:35 NaN 2406 4348 70715
18/07/2017 22:40 NaN 4756 3744 NaN
18/07/2017 22:45 NaN 3988 2915 NaN
18/07/2017 22:50 2280 3058 2120 NaN
18/07/2017 22:55 2 NaN 1939 NaN
18/07/2017 23:00 2 NaN 2256 NaN
18/07/2017 23:05 2121 NaN 2640 2025
18/07/2017 23:10 3367 2 2202 1916
18/07/2017 23:15 3247 NaN NaN 2
18/07/2017 23:20 2491 NaN NaN 2
18/07/2017 23:25 2010 NaN NaN 1560
18/07/2017 23:30 1899 NaN 1366 1355
18/07/2017 23:35 1992 2265 1236 NaN
18/07/2017 23:40 2196 4407 2 NaN
18/07/2017 23:45 1961 3848 2 NaN
18/07/2017 23:50 NaN 2880 2809 4565
18/07/2017 23:55 NaN 2143 2397 3725
19/07/2017 00:00 NaN 1981 NaN 2921
19/07/2017 00:05 NaN 2227 NaN 2131
19/07/2017 00:10 1366 2526 NaN 1990
答案 0 :(得分:1)
shift
,使用np.logical_and.reduce
和np.logical_or.reduce
创建遮罩(或双精度位置)。
import numpy as np
import pandas as pd
Nmin = 3 # At least 2
m = pd.DataFrame(np.logical_and.reduce([(df == df.shift(i)).to_numpy() for i in range(1, Nmin)]))
df = df.where(df.where(m.to_numpy()).bfill(limit=Nmin-1).isnull())
#df = df.mask(np.logical_or.reduce([m.shift(-i).fillna(False).to_numpy() for i in range(Nmin)]))
df
Date London Paris Dubai Tokyo
0 18/07/2017-22:35 NaN 2406.0 4348.0 70715.0
1 18/07/2017-22:40 NaN 4756.0 3744.0 NaN
2 18/07/2017-22:45 NaN 3988.0 2915.0 NaN
3 18/07/2017-22:50 2280.0 3058.0 2120.0 NaN
4 18/07/2017-22:55 2.0 NaN 1939.0 NaN
5 18/07/2017-23:00 2.0 NaN 2256.0 NaN
6 18/07/2017-23:05 2121.0 NaN 2640.0 2025.0
7 18/07/2017-23:10 3367.0 2.0 2202.0 1916.0
8 18/07/2017-23:15 3247.0 NaN NaN 2.0
9 18/07/2017-23:20 2491.0 NaN NaN 2.0
10 18/07/2017-23:25 2010.0 NaN NaN 1560.0
11 18/07/2017-23:30 1899.0 NaN 1366.0 1355.0
12 18/07/2017-23:35 1992.0 2265.0 1236.0 NaN
13 18/07/2017-23:40 2196.0 4407.0 2.0 NaN
14 18/07/2017-23:45 1961.0 3848.0 2.0 NaN
15 18/07/2017-23:50 NaN 2880.0 2809.0 4565.0
16 18/07/2017-23:55 NaN 2143.0 2397.0 3725.0
17 19/07/2017-00:00 NaN 1981.0 NaN 2921.0
18 19/07/2017-00:05 NaN 2227.0 NaN 2131.0
19 19/07/2017-00:10 1366.0 2526.0 NaN 1990.0
答案 1 :(得分:0)
如果您的代码正常且快速运行-只需跨列对其进行迭代:
for col in df.columns:
g = df.[col].diff().fillna(0).ne(0).cumsum()
# and so on...