在 Pandas 中应用多个条件来选择当前和前一行。

3

我有一个数据框如下所示:

person_id  source_system   r_diff
  1              O          NULL
  1              O           0
  1              O           9
  1              O           NULL
  2              O           574
  2              I           20
  2              O           135
  2              O           0
  2              I           21
  2              O           2
  2              O           0
  2              O           0
  2              I           12 

我想根据以下条件选择行:

条件1-选择所有源系统为I的行

条件2-仅在(n-1)行的源系统为O且差异为零时,才选择上一行 (n-1)。

只有当第n行的源系统为I时才应用此条件2。 如果(n-1)行的源系统是I,则我们不必做任何操作,因为条件1将处理它。

我们必须对每个人都应用这两个条件

我尝试了以下根据SO建议,但不确定如何使其工作。

m1 = df['visit_source_value'] == 'I'
m2 = df['diff'] <= 0
m3 = df.groupby('person_id')['diff'].shift(-1) <= 0 

df = df1[m1 | m2 | m3]

我期望我的输出结果如下所示。
  2              I           20
  2              O           0
  2              I           21
  2              O           0
  2              I           12 
2个回答

1

我更喜欢不使用一行代码的解决方案,因为如果代码变得更加复杂,那么很难阅读。所以最好的方法是使用:

m1 = df['visit_source_value'] == 'I'
m2 = df['r_diff'] <= 0
m3 = df.groupby('person_id')['visit_source_value'].shift(-1) == 'I'

df = df[m1 | (m2 & m3)]

print (df)
    person_id visit_source_value  r_diff
5           2                  I    20.0
7           2                  O     0.0
8           2                  I    21.0
11          2                  O     0.0
12          2                  I    12.0

1
基本上会做更多或更少相同的事情,我同意分割掩码的想法。 - mozway
这个跟我的不一样吗? - U13-Forward
1
是的,它将条件拆分为掩码,更易读。 - mozway
好的,这种情况经常发生,不要感到沮丧,这只是一个简单的问题和简单的答案,没有什么值得生气的吧?很多时候,当我做类似的事情时(比如在这里),我会选择不发帖子。 - mozway
@U12-Forward - 刚刚测试了一下,发现你的解决方案没有按照组对 I 进行测试。 - jezrael

1
您可以用一行代码实现它:
>>> df[df['source_system'].eq('I') | (df['source_system'].shift(-1).eq('I') & df['r_diff'].le(0))]
    person_id source_system  r_diff
5           2             I    20.0
7           2             O     0.0
8           2             I    21.0
11          2             O     0.0
12          2             I    12.0
>>> 

除非 OP 没有提到其他可能的值,否则您不需要测试 df ['source_system'].eq('O') - mozway
@mozway 哦,没错!我编辑了我的回答。 - U13-Forward

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接