python - 如果在 Pandas 中连续满足一定条件,则更改值

标签 python pandas

仅当特定条件连续 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/

相关文章:

Python Exscript - JunOS

python - 在 SQLalchemy 中过滤左连接

python - 从数据中排除 2 个字符串

python - Pandas 从来自 Excel 的数据框中删除列和行

python - 使用 Pandas 内置除法时出现内存错误,但循环有效?

python - 如何使用pytest生成测试报告?

python - 在 for 循环中分组数据

python - pandas dataframe聚合计算

python - 规范化多维数组

python - 在 python 中的三个重叠集中查找增量