基于 df

问题描述

我想对以下 df 进行基于条件的比较。

     ID     type  state   value
0  123123     1    LOW      5
2  123123     2    LOW      8
5  123123     2    HIGH     2
7  123123     1    LOW      3
1  123412     2    HIGH     21
6  123412     1    LOW      12
3  234234     2    LOW      5
8  234234     1    LOW      1
4  432424     2    HIGH     9
9  432424     1    HIGH     7

所以我想要做的是检查列状态中的值是否为 LOW 的每一行,如果行中的以下值或之前的值是 HIGH。如果是这样,我想检查行类型中的值是否相同。如果再次满足此条件,我想检查此值之间的差异是否小于 2。如果是,名为 validate 的新列应为真,否则应为假。

总而言之,我正在寻找一种方法来检查这种情况的效率。

我考虑过用 apply 来做,但是我不确定如何检查给定行前后的值。

到目前为止,我只考虑通过遍历数据框来实现,但这应该是非常慢的......所以如果你们中的任何人知道如何解决这个问题,我将不胜感激。

结果应该是这样的:

     ID     type  state   value  valid
0  123123     1    LOW      5      False
2  123123     2    LOW      4      True
5  123123     2    HIGH     2      
7  123123     1    LOW      3      True
1  123412     1    HIGH     21     
6  123412     1    LOW      12     False
3  234234     2    LOW      5      False
8  234234     1    LOW      1      False
4  432424     2    HIGH     9      
9  432424     1    HIGH     7    

这里再次总结了行为真的基于行的条件

  • 行之前或之后的状态为 HIGH
  • 对于高的行(或者如果两者都适用)然后检查类型是否相同
  • 最后检查值之间的差异是否小于 2

解决方法

试试这个 -

df.loc[df.state == 'LOW','valid'] = False
df.loc[(df.state != df.state.shift(-1)) & (df.state == 'LOW'),'valid'] = True
,

使用 shift()diff()above | belowstatetype 条件创建 value 掩码。

below = df.state.eq('LOW') & df.state.shift(-1).eq('HIGH') & df.type.shift(-1).eq(df.type) & df.value.diff(-1).abs().le(2)
above = df.state.eq('LOW') & df.state.shift().eq('HIGH') & df.type.shift().eq(df.type) & df.value.diff().abs().le(2)

df.loc[df.state.eq('LOW'),'valid'] = False
df.loc[above | below,'valid'] = True

索引 7 的输出不同,但我不明白为什么您的预期输出显示 True,因为上面的 type 不同(1 对 2)和低于 value 的不同是 18:

       ID  type state  value  valid
0  123123     1   LOW      5  False
2  123123     2   LOW      4   True
5  123123     2  HIGH      2    NaN
7  123123     1   LOW      3  False
1  123412     2  HIGH     21    NaN
6  123412     1   LOW     12  False
3  234234     2   LOW      5  False
8  234234     1   LOW      1  False
4  432424     2  HIGH      9    NaN
9  432424     1  HIGH      7    NaN
,

您可以使用 df.shift 方法并将您的 df 与移位的 df 进行比较。这样就不需要循环了。