仅当特定条件连续 n
次满足时,我才会更改某些 DataFrame 值的值。
示例:
df = pd.DataFrame(np.random.randn(15, 3))
df.iloc[4:8,0]=40
df.iloc[12,0]=-40
df.iloc[10:12,1]=-40
这给了我这个 DF:
0 1 2
0 1.238892 0.802318 -0.013856
1 -1.136326 -0.527263 -0.260975
2 1.118771 0.031517 0.527350
3 1.629482 -0.158941 -1.045209
4 40.000000 0.598657 -1.268399
5 40.000000 0.442297 -0.016363
6 40.000000 -0.316817 1.744822
7 40.000000 0.193083 0.914172
8 0.322756 -0.680682 0.888702
9 -1.204531 -0.240042 1.416020
10 -1.337494 -40.000000 -1.195780
11 -0.703669 -40.000000 0.657519
12 -40.000000 -0.288235 -0.840145
13 -1.084869 -0.298030 -1.592004
14 -0.617568 -1.046210 -0.531523
现在,如果我这样做
a=df.copy()
a[ abs(a) > abs(a.std()) ] = float('nan')
我明白了
0 1 2
0 1.238892 0.802318 -0.013856
1 -1.136326 -0.527263 -0.260975
2 1.118771 0.031517 0.527350
3 1.629482 -0.158941 NaN
4 NaN 0.598657 NaN
5 NaN 0.442297 -0.016363
6 NaN -0.316817 NaN
7 NaN 0.193083 0.914172
8 0.322756 -0.680682 0.888702
9 -1.204531 -0.240042 NaN
10 -1.337494 NaN NaN
11 -0.703669 NaN 0.657519
12 NaN -0.288235 -0.840145
13 -1.084869 -0.298030 NaN
14 -0.617568 -1.046210 -0.531523
这是公平的。但是,如果最多 2 个连续条目满足这些条件,我只想用 NaN 替换这些值(这样我可以稍后进行插值)。例如,我想要的结果是
0 1 2
0 1.238892 0.802318 -0.013856
1 -1.136326 -0.527263 -0.260975
2 1.118771 0.031517 0.527350
3 1.629482 -0.158941 NaN
4 40.000000 0.598657 NaN
5 40.000000 0.442297 -0.016363
6 40.000000 -0.316817 NaN
7 40.000000 0.193083 0.914172
8 0.322756 -0.680682 0.888702
9 -1.204531 -0.240042 NaN
10 -1.337494 NaN NaN
11 -0.703669 NaN 0.657519
12 NaN -0.288235 -0.840145
13 -1.084869 -0.298030 NaN
14 -0.617568 -1.046210 -0.531523
显然没有现成的方法可以做到这一点。我发现最接近我的问题的解决方案是 this one ,但我无法让它为我工作。
有什么想法吗?
最佳答案
见下文 - 棘手的部分是 (cond[c] != cond[c].shift(1)).cumsum()
它将数据分成相同值的连续运行。
In [23]: cond = abs(df) > abs(df.std())
In [24]: for c in df.columns:
...: grouper = (cond[c] != cond[c].shift(1)).cumsum() * cond[c]
...: fill = (df.groupby(grouper)[c].transform('size') <= 2)
...: df.loc[fill, c] = np.nan
In [25]: df
Out[25]:
0 1 2
0 1.238892 0.802318 -0.013856
1 -1.136326 -0.527263 -0.260975
2 1.118771 0.031517 0.527350
3 1.629482 -0.158941 NaN
4 40.000000 0.598657 NaN
5 40.000000 0.442297 -0.016363
6 40.000000 -0.316817 NaN
7 40.000000 0.193083 0.914172
8 0.322756 -0.680682 0.888702
9 -1.204531 -0.240042 NaN
10 -1.337494 NaN NaN
11 -0.703669 NaN 0.657519
12 NaN -0.288235 -0.840145
13 -1.084869 -0.298030 NaN
14 -0.617568 -1.046210 -0.531523
再解释一下,cond[c]
是一个 bool 系列,指示您的条件是否为真。
cond[c] != cond[c].shift(1)
将当前行的条件与下一行的条件进行比较。这具有“标记”的效果,其中一系列值以值 True
开头。
.cumsum()
将 bool 值转换为整数并获取累积和。它可能不是立即直观的,但是这对连续值组进行了“编号”。最后,* cond[c]
将所有不符合条件的组重新分配为 0(使用 False == 0
)
现在您已经有了满足条件的连续数字组,下一步执行 groupby
来计算每个组中有多少个值 (transform('size')
.
最后,使用新的 bool 条件将缺失值分配给具有 2 个或更少值满足条件的组。
关于python - 如果在 Pandas 中连续满足一定条件,则更改值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32850185/